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已经在评论中提到了这一点。我错过了。