delete在函数结束时不释放内存

时间:2021-06-13 21:21:59

I'm nearing my wits end with this. I have searched for hours for a solution to this, but I haven't found something that solves my problem.

我已经接近我的智慧了。我已经搜索了几个小时来解决这个问题,但我找不到能解决问题的方法。

So I want to code a neuronal network and I have written extensive code for it and which I have checked and debugged so far. I tried evolving my network over multiple generations but although it does execute it gives me a double free or corruption error. I have traced the error with valgrind to this 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 gives me a mismatched free()/delete/delete[] error at where element_already_mutated gets initialized and free'd. The funky thing is, if I comment the dynamic allocation out and just initialize my "workaround" which is just a normal static array, I get no memory leaks and everything gets deallocated correctly. NUM_I is defined as 4 in the header as:

Valgrind给出了一个不匹配的free()/ delete / delete []错误,其中element_already_mutated被初始化和释放。时髦的事情是,如果我评论动态分配并只是初始化我的“解决方法”,这只是一个普通的静态数组,我没有内存泄漏,所有内容都被正确释放。 NUM_I在标头中定义为4:

#define NUM_I 4

Valgrind error:

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)

Can someone tell me what I'm doing wrong? I don't think I'm deallocating incorrectly but I have no idea where the error might be otherwise.

有人能告诉我我做错了什么吗?我认为我没有错误地解除分配,但我不知道错误可能在哪里。

2 个解决方案

#1


1  

You sometimes delete it, and sometimes don't. This is the primary reason this whole method of coding is strongly discouraged. Here is your code with some extra stuff removed so you can see it more clearly:

你有时删除它,有时不删除它。这是强烈建议不要使用整个编码方法的主要原因。这是您的代码,删除了一些额外的东西,以便您可以更清楚地看到它:

bool mutate_a_neuron(...){
    bool* element_already_mutated = new bool[num_e];

    if( condition ){
        // not deleted
        return true;
    }

    delete [] element_already_mutated;
    return false;
}

edit: actually UnholySheep already mentioned this in the comments. I missed that.

编辑:实际上UnholySheep已经在评论中提到了这一点。我错过了。

#2


1  

Given the function you did show, the simplest way to avoid the memory leak (if this function is indeed the only one leaking memory) is to use std::vector.

鉴于您所显示的功能,避免内存泄漏的最简单方法(如果此函数确实是唯一泄漏的内存)是使用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) The initialization of the vector elements to false is automatically done on construction of the vector, thus the for loop that initialized the boolean array to false is no longer needed.

1)矢量元素初始化为false是在构造向量时自动完成的,因此不再需要将布尔数组初始化为false的for循环。

2) The call to delete [] element_already_mutated; must be removed, since element_already_mutated is no longer a pointer. In addition, vector will automatically deallocate memory it has allocated, thus another reason to remove the delete [].

2)调用delete [] element_already_mutated;必须删除,因为element_already_mutated不再是指针。另外,vector会自动释放它已分配的内存,因此删除delete []的另一个原因。

3) The return true; statement you had no longer will cause an issue, since if the mutate_a_neuron function returns for any reason, the vector<bool> will be destroyed, thus removing any chance of a memory leak.

3)返回true;声明你不再会引起问题,因为如果mutate_a_neuron函数因任何原因返回,那么vector 将被销毁,从而消除任何内存泄漏的可能性。

4) Since the code that uses vector makes accesses using [], the rest of the code does not need to be changed, since std::vector overloads operator [] to act as an array.

4)由于使用向量的代码使用[]进行访问,因此不需要更改其余代码,因为std :: vector重载operator []作为数组。

#1


1  

You sometimes delete it, and sometimes don't. This is the primary reason this whole method of coding is strongly discouraged. Here is your code with some extra stuff removed so you can see it more clearly:

你有时删除它,有时不删除它。这是强烈建议不要使用整个编码方法的主要原因。这是您的代码,删除了一些额外的东西,以便您可以更清楚地看到它:

bool mutate_a_neuron(...){
    bool* element_already_mutated = new bool[num_e];

    if( condition ){
        // not deleted
        return true;
    }

    delete [] element_already_mutated;
    return false;
}

edit: actually UnholySheep already mentioned this in the comments. I missed that.

编辑:实际上UnholySheep已经在评论中提到了这一点。我错过了。

#2


1  

Given the function you did show, the simplest way to avoid the memory leak (if this function is indeed the only one leaking memory) is to use std::vector.

鉴于您所显示的功能,避免内存泄漏的最简单方法(如果此函数确实是唯一泄漏的内存)是使用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) The initialization of the vector elements to false is automatically done on construction of the vector, thus the for loop that initialized the boolean array to false is no longer needed.

1)矢量元素初始化为false是在构造向量时自动完成的,因此不再需要将布尔数组初始化为false的for循环。

2) The call to delete [] element_already_mutated; must be removed, since element_already_mutated is no longer a pointer. In addition, vector will automatically deallocate memory it has allocated, thus another reason to remove the delete [].

2)调用delete [] element_already_mutated;必须删除,因为element_already_mutated不再是指针。另外,vector会自动释放它已分配的内存,因此删除delete []的另一个原因。

3) The return true; statement you had no longer will cause an issue, since if the mutate_a_neuron function returns for any reason, the vector<bool> will be destroyed, thus removing any chance of a memory leak.

3)返回true;声明你不再会引起问题,因为如果mutate_a_neuron函数因任何原因返回,那么vector 将被销毁,从而消除任何内存泄漏的可能性。

4) Since the code that uses vector makes accesses using [], the rest of the code does not need to be changed, since std::vector overloads operator [] to act as an array.

4)由于使用向量的代码使用[]进行访问,因此不需要更改其余代码,因为std :: vector重载operator []作为数组。