«Std :: bad_alloc»: Я использую слишком много памяти?
Вопрос
Сообщение:
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
Я посмотрел на Backtrace GDB, и это метод самого низкого уровня, который я реализовал сам:
/*
* get an array of vec3s, which will be used for rendering the image
*/
vec3 *MarchingCubes::getVertexNormalArray(){
// Used the same array size technique as getVertexArray: we want indices to match up
vec3 *array = new vec3[this->meshPoints.getNumFaces() * 3]; //3 vertices per face
int j=0;
for (unsigned int i=0; i < (this->meshPoints.getNumFaces() * 3); i++) {
realVec normal = this->meshPoints.getNormalForVertex(i);
// PCReal* iter = normal.begin();
if (normal.size() >= 3) {
array[j++] = vec3(normal[0], normal[1], normal[2]);
}
cout << i << " ";
}
return array;
}
Оператор COUT, который вы видите выше, указывает на то, что оно завершается после 7000+ итераций. Вышеуказанная функция называется только один раз ближе к концу моего приложения. Я называю очень похожую функцию, прежде чем вызовать выше, это не вызывает проблем.
Решение 2
Моя проблема оказалась, что this->meshPoints.getNormalForVertex(i)
Доступ к массиву (или вектору, я не могу вспомнить), длина которой меньше, чем this->meshPoints.getNumFaces() * 3
. Анкет Так что он был за пределами границ.
Другие советы
(Перемещение/расширение из комментариев)
Поскольку вы каждый раз выделяете новый массив, не складывая его, у вас есть огромная утечка памяти, то есть вы продолжаете задавать память в систему, даже не возвращая ее. В конце концов пространство на куче финиширует, и при следующем распределении все, что вы получите, это std::bad_alloc
исключение.
Решение «C-C-Style» было бы помнить, чтобы разобраться в такой памяти, когда вам больше не нужно (с delete[]
), но это (1) склонность к ошибкам (например, например, если у вас есть несколько возвратных путей внутри функции) и (2) потенциально исключение-Unsafe (каждая инструкция становится потенциальным пути возврата, если у вас есть исключения!). Таким образом, этого способа следует избегать.
Идиоматическое решение C ++ - это использовать либо Умные указатели - Маленькие объекты, которые инкапсулируют указатель и разбирают связанную память, когда они уничтожаются - или стандартные контейнеры, которые делают более или менее одно и то же, но с семантикой копирования и некоторыми большим количеством наворотов и свистков (включая хранение размера внутри массива внутри них) Анкет
Я получил эту ошибку, пытаясь выделить массив отрицательной длины:
Double myarray = new Double [-9000];
На случай, если это поможет кому -либо.