Как исправить ошибку C++: завершение вызывается после создания экземпляра 'std::bad_alloc'. что(): std::bad_alloc

Мои извинения, я знаю, что на этот тип вопроса уже есть ответ здесь, но я не мог понять, как использовать его для своего кода. Я написал программу для соревнования по решению задач, которая принимает массив и пытается максимизировать значение |Ax-Ay|+|Ay-Az|+|Az-Ax| по всем тройкам попарно различных действительных индексов (x, y, z). Программа имеет следующие ограничения:

  • 1≤t≤5
  • 3≤n≤10^5
  • |Ai|≤10^9 для каждого действительного i

Я получаю следующую ошибку, когда пытаюсь запустить его: вызывается завершение после создания экземпляра 'std::bad_alloc' what(): std::bad_alloc. Все, что я смог понять из ответов на вопросы, это то, что мой код сталкивается с проблемой выделения памяти, но я не мог найти, где и когда это происходит? Может быть, когда речь идет о больших значениях? Что вызывает ошибку?

#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef vector<ll> vll;
typedef vector<int> vi;

#define rep(i, a, b) for (ll i = a; i < b; i++)
#define repi(i, a, b) for (ll i = a; i <= b; i++)
#define repn(i, a, b) for (ll i = a; i >= b; i--)
#define fast()                        \
    ios_base::sync_with_stdio(false); \
    cin.tie(NULL);                    \
    cout.tie(NULL)
#define all(x) (x).begin(), (x).end()
// solve() function
void solve()
{
    ll n;
    cin >> n;
    vll v(n);
    rep(i, 0, n)
            cin >>
        v[i];
    sort(all(v));
    ll x = v[0], y = v[1], z = v[n - 1];
    ll ans = abs(x - y) + abs(y - z) + abs(z - x);
    cout << ans << endl;
}
// driver function
int main()
{
    fast();
    ll t = 1;
    cin >> t;
    rep(i, 0, t)
    {
        solve();
    }
    return 0;
}

Формат ввода следующий:

Input
The first line of the input contains a single integer T denoting the number of test cases. The description of T test cases follows.
The first line of each test case contains a single integer N.
The second line contains N space-separated integers A1, A2,…,AN.

Ниже приведен пример ввода:

3
3
2 7 5
3
3 3 3
5
2 2 2 2 5

person Mohit Singh    schedule 08.02.2021    source источник
comment
может быть, вы ввели n, который очень большой, но вектор не может выделить столько памяти, чтобы зарезервировать столько, сколько вам нужно для этого vll.reserve(n). это может решить вашу проблему, потому что при вводе n вектор выделяет больше памяти, чем нужно, зависит от реализации компилятора.   -  person foragerDev    schedule 08.02.2021
comment
Пожалуйста, расшифруйте код, если хотите, чтобы мы попытались его проанализировать. Вы также должны добавить ввод программы и точную точку, в которой возникает исключение. Вопиющая проблема, которую я вижу, это отсутствие проверки ошибок ввода: вы должны дважды проверить, что t и особенно n имеют разумные значения.   -  person Quentin    schedule 08.02.2021
comment
Что делаешь? В чем проблема написать простой цикл? Зачем вам использовать определения! НЕТ. это подвержено ошибкам, как вы видите в своем коде.   -  person JHBonarius    schedule 08.02.2021
comment
@JHBonarius Это часть шаблона конкурса. Я использую его только тогда, когда участвую в соревнованиях на время, чтобы сэкономить время при написании кода. Я стараюсь уделять как можно больше времени процессу обдумывания конкурсной задачи. Обычно я пишу код не так.   -  person Mohit Singh    schedule 08.02.2021
comment
Только ваш первый ans использует три различных индекса. Два других эквивалентны 2 * abs(v[1] - v[n-1]) и 2 * abs(v[0] - v[n-1]), и первое не может быть больше второго. (Насколько я могу судить, это почти вопрос с подвохом; я не думаю, что вам нужен вектор или какая-либо сортировка.)   -  person molbdnilo    schedule 08.02.2021
comment
@molbdnilo Спасибо. Я понял вашу мысль и внес изменения в код. Что касается вашего второго аргумента о необходимости вектора или сортировки, я добавил формат ввода, поставляемый с задачей, а также пример ввода.   -  person Mohit Singh    schedule 08.02.2021
comment
@MohitSingh Даже в вашем решении используются только самые маленькие, вторые по величине и самые большие числа. Вы можете определить их из произвольно большого количества входных данных, не сохраняя более трех чисел. (И вам на самом деле нужно только два. Примените немного алгебры.)   -  person molbdnilo    schedule 09.02.2021
comment
@molbdnilo Спасибо! Я понял вашу точку зрения, и на самом деле требовалось только 2 числа. Я сформулировал решение, и оно прошло все тесты. Еще раз спасибо.   -  person Mohit Singh    schedule 10.02.2021


Ответы (1)


вам нужно сделать что-то вроде этого: я не получаю данные через cin, я просто указываю значение.

void solve()
{
    ll n =100000000; 
    vll v;
    v.reserve(n);
    //omitted
}

он работает нормально, и он не выдает ошибку bad_alloc. В вашем случае n может быть неинициализирован и не получает допустимого ввода, поэтому он пропускает n, который очень большой. когда vll v(n) пытается выделить, ему не хватает памяти и returns 137, что означает нехватку памяти. так что это не удается. Если вы укажете n непосредственно в конструкторе vector, он выделит больше памяти (зависит от компилятора). Но если вы зарезервируете необходимую вам память, она будет работать нормально, пока у вас не будет достаточно памяти для хранения данных, которые вы помещаете в файл vector.

person foragerDev    schedule 08.02.2021