Ошибка 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];
}