valgrind对吗?记忆力丢失了吗?

时间:2011-06-20 17:00:47

标签: c valgrind

typedef struct Model
{
    int recordId;
    char *name;
}Model;

typedef struct ModelArray
{
    //keeps the size that the array was initially create with. When more elements are needed
    //we use this to add that many more elements
    int originalSize;
    //total number of elements that can be used
    int elements;
    //total number of elements used
    int count;
    //the actual array is stored here
    Model *source;
}ModelArray;

void initModelArray(ModelArray *array, int numberOfElements)
{
    array->originalSize = numberOfElements;
    array->elements = numberOfElements;
    array->count = 0;
    array->source = malloc(sizeof(Model)*numberOfElements);//0 bytes in 3 blocks are definitely lost in loss record 1 of 65
}

void deallocModelArray(ModelArray *array)
{
    if(array == NULL)
        return;

    array->elements = 0;
    array->count = 0;
    free(array->source);
    array->source = NULL;
    free(array);
}

main(int argc, const char * argv[])
{
    ModelArray *models = malloc(sizeof(ModelArray));
    initModelArray(models, 10);
    deallocModelArray(models);
}

丢失了什么?代码看起来很好。我敢肯定我可以先说array-> source = NULL但是不需要它,对吗?

2 个答案:

答案 0 :(得分:7)

要正确释放这些结构,您需要按以下顺序执行以下操作:

free(models->source);
free(models);

如果你做了其他事情,你就会泄漏记忆。

编辑:

好的,看过Model结构,你可能泄漏了名字,或者至少valgrind认为你这样做是因为你释放了ModelArray结构,它包含一个指向Model结构的指针,该结构包含一个你不喜欢的char *先免费。

所以:

int i;
for( i=0; i<models->originalSize; i++ ) {
    if( models->source[i]->name != NULL ) {
        free( models->source[i]->name );
    }
}
free(models->source);
free(models);

在首先分配models-&gt; source时使用calloc()而不是malloc()是个好主意。这会将所有名称指针设置为0.如果没有这个,如果名称恰好包含一些垃圾,那么上面的模型 - &gt; source [i] - &gt;名称为非NULL的测试可能会失败(因为使用未初始化的内存会产生未定义的行为。)

答案 1 :(得分:2)

呃......是的,记忆力已经消失了。当然,它丢失了,因为你“省略了dealloc代码”!

当你“遗漏dealloc代码”时,你怎么能指望任何人回答你的问题?你的问题的本质是你的dealloc代码是否正确。你决定把它留下来?

最重要的是,你的代码中有很多东西没什么意义。什么是

typedef struct ModelArray {
  ...
  Model *source; 
  ...
} Model;

应该是什么意思?您为什么要键入struct ModelArrayModel?实际上,您的代码甚至不会编译,因为Model *在结构中使用,而它尚未声明。您还在代码中使用ModelArray类型,而实际上没有这种类型。您有struct ModelArray,但不仅仅是ModelArray。您发布的代码不是真正的代码。请发布实际代码。 (显然它应该是typedef struct ModelArray { ... } ModelArray;Model在别处定义。)

最后,作为一个不相关的注释,//注释是C99功能。在C99中,函数返回类型不能省略(C99中没有“implicit int”规则),这意味着您必须将main函数声明为int main