«Std :: bad_alloc»: Я использую слишком много памяти?

StackOverflow https://stackoverflow.com/questions/8378797

  •  28-10-2019
  •  | 
  •  

Вопрос

Сообщение:

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];

На случай, если это поможет кому -либо.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top