"STD :: BAD_ALLOC": Sto usando troppa memoria?
Domanda
Il messaggio:
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
Ho guardato il backtrace GDB e questo è il metodo di livello più basso che mi sono implementato:
/*
* 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;
}
L'istruzione Cout che vedi sopra indica che termina dopo oltre 7000 iterazioni. La funzione sopra è chiamata solo una volta vicino alla fine della mia applicazione. Chiamo una funzione molto simile prima di chiamare quanto sopra, che non causa problemi.
Soluzione 2
Il mio problema si è rivelato essere quello this->meshPoints.getNormalForVertex(i)
accede a un array (o vettore, non ricordo) la cui lunghezza è inferiore a this->meshPoints.getNumFaces() * 3
. Quindi stava accedendo ai limiti.
Altri suggerimenti
(spostamento/espansione dai commenti)
Dal momento che stai assegnando un nuovo array ogni volta senza trattarlo, hai una massiccia perdita di memoria, cioè continui a chiedere la memoria al sistema senza mai restituirlo. Alla fine lo spazio sul heap termina e alla prossima allocazione tutto ciò che ottieni è un std::bad_alloc
eccezione.
La soluzione "in stile C" sarebbe quella di ricordare di traffrire tale memoria quando non ne hai più bisogno (con delete[]
), ma questo è (1) soggetto a errori (pensa ad es. Se si dispone di più percorsi di ritorno all'interno di una funzione) e (2) potenzialmente Exception-Unsafe (ogni istruzione diventa un potenziale percorso di ritorno se hai eccezioni!). Pertanto, in questo modo dovrebbe essere evitato.
La soluzione idiomatica C ++ è usare Pointatori intelligenti - Piccoli oggetti che incapsulano il puntatore e si occupano della memoria associata quando vengono distrutti - o contenitori standard, che fanno più o meno la stessa cosa, ma con la semantica di copia e alcune più campane e fischietti (incluso la memorizzazione delle dimensioni dell'array al loro interno) .
Ho ricevuto questo errore che cerca di allocare un array di lunghezza negativa:
Double MyArray = new Double [-9000];
Nel caso in cui aiuti chiunque.