删除函数末尾没有释放内存

时间:2017-12-07 21:05:49

标签: c++ memory memory-management free

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

所以我想编写一个神经网络,我已经编写了大量的代码,到目前为止我已经检查和调试过。我试过在几代人中改进我的网络但是虽然它确实执行了但它给了我一个双重免费或损坏错误。我用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给我一个不匹配的free()/ delete / delete []错误,其中element_already_mutated被初始化并且是免费的。时髦的是,如果我评论动态分配,只是初始化我的&#34;解决方法&#34;这只是一个普通的静态数组,我没有内存泄漏,所有内容都被正确释放。 NUM_I在标题中定义为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)

有人可以告诉我我做错了什么吗?我不认为我解密错误,但我不知道错误可能在哪里。

2 个答案:

答案 0 :(得分:1)

鉴于您所展示的功能,避免内存泄漏的最简单方法(如果此功能确实是唯一一个泄漏内存)是使用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的{​​{1}}循环是不再需要了。

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

3)你不再有delete []语句会导致问题,因为如果return true;函数因任何原因返回,mutate_a_neuron将被销毁,从而消除任何机会内存泄漏。

4)由于使用vector<bool>的代码使用vector进行访问,因此不需要更改其余代码,因为[]会重载std::vector以执行操作作为一个数组。

答案 1 :(得分:1)

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

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