delete 不会在函数结束时释放内存
delete doesn't free memory at the end of a function
我的智慧快要用完了。我已经搜索了几个小时来解决这个问题,但我还没有找到解决我问题的方法。
所以我想编写一个神经元网络代码,我已经为它编写了大量代码,并且到目前为止我已经检查和调试了这些代码。我尝试将我的网络发展多代,但尽管它确实执行了,但它给了我一个双重释放或损坏错误。我已将 valgrind 的错误追踪到此函数
bool mutate_a_neuron(Neuron* neuron, int numberofneurons, int numberofinputs){
int num_e = 3*NUM_I+3;
bool* element_already_mutated = new bool[num_e]; //line 91
//bool element_already_mutated[15]; //Workaround :(
for(int i =0; i<num_e; i++){
element_already_mutated[i]=false;
}
int number_of_elements = (int) neuron->numberofelementstomutate;
unsigned short will_it_be_mutated = rand() % USHRT_MAX ;
if( neuron->mutationrate > will_it_be_mutated ){
for(int i = 0; i<number_of_elements; i++){
int elementtomutate = rand() % num_e; //choose random element
if(element_already_mutated[elementtomutate]){//check if mutated
i--;
continue;
}
if( mutate_element(neuron, elementtomutate, numberofneurons, numberofinputs) ){//mutate stuff
element_already_mutated[elementtomutate]=true;
} else {
printf("Something went wrong while mutating an element or takes_input was false\n"); //die if error
}
}
return true;
}
delete [] element_already_mutated; //line 120
return false;
}
Valgrind 在 element_already_mutated 初始化和释放的位置给我一个不匹配的 free()/delete/delete[] 错误。奇怪的是,如果我注释掉动态分配并初始化我的 "workaround" 这只是一个普通的静态数组,我不会发生内存泄漏并且所有内容都会正确释放。 NUM_I在header中定义为4为:
#define NUM_I 4
Valgrind 错误:
==1887== 15,023,190 bytes in 1,001,546 blocks are definitely lost in loss record 1 of 1
==1887== at 0x4C2C93F: operator new[](unsigned long) (vg_replace_malloc.c:423)
==1887== by 0x10A461: mutate_a_neuron(Neuron*, int, int) (n.cpp:91)
==1887== (here follow more functions, which call mutate_a_neuron)
有人可以告诉我我做错了什么吗?我不认为我的分配不正确,但我不知道错误可能出在哪里。
鉴于您展示的函数,避免内存泄漏的最简单方法(如果该函数确实是唯一一个泄漏内存的函数)是使用 std::vector。
#include <vector>
bool mutate_a_neuron(Neuron* neuron, int numberofneurons, int numberofinputs){
int num_e = 3*NUM_I+3;
std::vector<bool> element_already_mutated(num_e);
int number_of_elements = (int) neuron->numberofelementstomutate;
unsigned short will_it_be_mutated = rand() % USHRT_MAX ;
//...
// rest of your code
//
// delete [] element_already_mutated is no longer needed
return false;
}
1) vector
元素到 false
的初始化是在构建向量时自动完成的,因此 for
循环将布尔数组初始化为 false
不再需要。
2) 必须删除对 delete [] element_already_mutated;
的调用,因为 element_already_mutated
不再是指针。此外,vector
将自动释放已分配的内存,因此删除 delete []
.
的另一个原因
3) 您的 return true;
语句将不再引起问题,因为如果 mutate_a_neuron
函数 returns 出于任何原因, vector<bool>
将被破坏,从而消除任何内存泄漏的可能性。
4) 由于使用 vector
的代码使用 []
进行访问,因此不需要更改其余代码,因为 std::vector
重载了 operator []
充当数组。
您有时会删除它,有时不会。这是强烈反对整个编码方法的主要原因。这是您的代码,删除了一些额外的内容,以便您可以更清楚地看到它:
bool mutate_a_neuron(...){
bool* element_already_mutated = new bool[num_e];
if( condition ){
// not deleted
return true;
}
delete [] element_already_mutated;
return false;
}
编辑:实际上UnholySheep已经在评论中提到了这一点。我错过了。
我的智慧快要用完了。我已经搜索了几个小时来解决这个问题,但我还没有找到解决我问题的方法。
所以我想编写一个神经元网络代码,我已经为它编写了大量代码,并且到目前为止我已经检查和调试了这些代码。我尝试将我的网络发展多代,但尽管它确实执行了,但它给了我一个双重释放或损坏错误。我已将 valgrind 的错误追踪到此函数
bool mutate_a_neuron(Neuron* neuron, int numberofneurons, int numberofinputs){
int num_e = 3*NUM_I+3;
bool* element_already_mutated = new bool[num_e]; //line 91
//bool element_already_mutated[15]; //Workaround :(
for(int i =0; i<num_e; i++){
element_already_mutated[i]=false;
}
int number_of_elements = (int) neuron->numberofelementstomutate;
unsigned short will_it_be_mutated = rand() % USHRT_MAX ;
if( neuron->mutationrate > will_it_be_mutated ){
for(int i = 0; i<number_of_elements; i++){
int elementtomutate = rand() % num_e; //choose random element
if(element_already_mutated[elementtomutate]){//check if mutated
i--;
continue;
}
if( mutate_element(neuron, elementtomutate, numberofneurons, numberofinputs) ){//mutate stuff
element_already_mutated[elementtomutate]=true;
} else {
printf("Something went wrong while mutating an element or takes_input was false\n"); //die if error
}
}
return true;
}
delete [] element_already_mutated; //line 120
return false;
}
Valgrind 在 element_already_mutated 初始化和释放的位置给我一个不匹配的 free()/delete/delete[] 错误。奇怪的是,如果我注释掉动态分配并初始化我的 "workaround" 这只是一个普通的静态数组,我不会发生内存泄漏并且所有内容都会正确释放。 NUM_I在header中定义为4为:
#define NUM_I 4
Valgrind 错误:
==1887== 15,023,190 bytes in 1,001,546 blocks are definitely lost in loss record 1 of 1
==1887== at 0x4C2C93F: operator new[](unsigned long) (vg_replace_malloc.c:423)
==1887== by 0x10A461: mutate_a_neuron(Neuron*, int, int) (n.cpp:91)
==1887== (here follow more functions, which call mutate_a_neuron)
有人可以告诉我我做错了什么吗?我不认为我的分配不正确,但我不知道错误可能出在哪里。
鉴于您展示的函数,避免内存泄漏的最简单方法(如果该函数确实是唯一一个泄漏内存的函数)是使用 std::vector。
#include <vector>
bool mutate_a_neuron(Neuron* neuron, int numberofneurons, int numberofinputs){
int num_e = 3*NUM_I+3;
std::vector<bool> element_already_mutated(num_e);
int number_of_elements = (int) neuron->numberofelementstomutate;
unsigned short will_it_be_mutated = rand() % USHRT_MAX ;
//...
// rest of your code
//
// delete [] element_already_mutated is no longer needed
return false;
}
1) vector
元素到 false
的初始化是在构建向量时自动完成的,因此 for
循环将布尔数组初始化为 false
不再需要。
2) 必须删除对 delete [] element_already_mutated;
的调用,因为 element_already_mutated
不再是指针。此外,vector
将自动释放已分配的内存,因此删除 delete []
.
3) 您的 return true;
语句将不再引起问题,因为如果 mutate_a_neuron
函数 returns 出于任何原因, vector<bool>
将被破坏,从而消除任何内存泄漏的可能性。
4) 由于使用 vector
的代码使用 []
进行访问,因此不需要更改其余代码,因为 std::vector
重载了 operator []
充当数组。
您有时会删除它,有时不会。这是强烈反对整个编码方法的主要原因。这是您的代码,删除了一些额外的内容,以便您可以更清楚地看到它:
bool mutate_a_neuron(...){
bool* element_already_mutated = new bool[num_e];
if( condition ){
// not deleted
return true;
}
delete [] element_already_mutated;
return false;
}
编辑:实际上UnholySheep已经在评论中提到了这一点。我错过了。