Ошибка C++ bad_alloc после успешного выполнения кода несколько раз

Я относительно новичок в C++, и у меня возникла проблема с моим проектом. Я запускал следующий код несколько раз без проблем, но теперь, когда я пытаюсь запустить его, он выдает ошибку std::bad_alloc. Код написан на C++, но некоторые строки являются эксклюзивными для ROOT, которая написана на C++ для физиков элементарных частиц.

class Particle {
public:
    int pdgid;
    float px;

    Particle(int pdg, float px){
        pdgid = pdg;
        px = px;
    }
};

TFile* file = new TFile("filename.root");      //ROOT code, where particle values are obtained from. 
TTree* tree = (TTree*)file->Get("FlatTree");   //tree is where all events and associated values are held

vector<Particle> allparticles;

for (unsigned iEntry = 0; iEntry<tree->GetEntries(); iEntry++) {
    tree->GetEntry(iEntry);
    for (int iVecEntry = 0; iVecEntry < nfsp; iVecEntry++) {
        allparticles.push_back(Particle(pdg[iVecEntry],px[iVecEntry]));
    }
}

Код работает, если я уменьшу предел первого цикла for. Количество записей достаточно велико (более 2 миллионов), и nfsp может быть до 24 в зависимости от события. Это привело к тому, что векторные частицы имели более 7 миллионов объектов частиц.

Я думаю, что проблема заключается в нехватке памяти для выделения такого большого вектора, но как это работало ранее? Возможно ли, что память не была должным образом освобождена в первые несколько раз, когда я запускал код?

Я немного запутался в управлении памятью. В C++ ОС обрабатывает освобождение? Или я должен включить деструктор?

Я попытался включить деструктор, но не смог заставить его работать. Из "std::bad_alloc": я использую слишком много памяти? Я попытался включить оператор delete[] в конец кода, но это также не работает.

Любой вклад и помощь очень ценится!

PS У меня работает linux mint 18.2 Соня.

1 ответ

Да, звучит так, как будто у вас закончилась память стека. Вот один из множества уроков, которые объясняют кучу и память стека.

Вы создаете свои частицы в стековой памяти, так что это означает, что они будут автоматически уничтожены, когда они выйдут из области видимости. Размер стековой памяти варьируется в зависимости от компилятора и среды, но вы получаете намного меньше стековой памяти, чем кучная память.

Чтобы это исправить, я бы создал вектор указателей на частицы и создавал частицы динамически. Пример:

vector<Particle*> allparticles;
...
allparticles.push_back(new Particle(pdg[iVecEntry],px[iVecEntry]));

Помните, чтобы удалить динамически распределенную память кучи, когда вы закончите с ней. Пример:

for(int i < 0; i < allparticles.size(); i++){
    delete allparticles[i];
}
Другие вопросы по тегам