valgrind 正确吗?记忆丢失了吗?

发布于 2024-11-16 07:55:15 字数 1215 浏览 2 评论 0原文

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 但不需要,对吗?

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);
}

What is lost? Code looks fine to me. I'm sure I could say array->source = NULL first but it's not needed, right?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

奈何桥上唱咆哮 2024-11-23 07:55:15

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

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->source 时,最好使用 calloc() 而不是 malloc()。这会将所有 name 指针设置为 0。如果没有这个,如果 name 碰巧包含一些垃圾,上面对 models->source[i]->name 为非 NULL 的测试可能会失败(因为使用未初始化的内存会产生未定义的行为.)

To deallocate these structures correctly, you need to do the following, in this order:

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

If you do anything else, you're leaking memory.

Edit:

OK, having seen the Model struct, you're probably leaking the names, or at least valgrind thinks you do because you deallocate the ModelArray structure, which contains a pointer to a Model structure, which contains a char* which you don't free first.

So:

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);

And it would be a good idea to use calloc() instead of malloc() when allocating models->source in the first place. This will set all the name pointers to 0. Without this, the test for models->source[i]->name being non-NULL above might fail if name happens to contain some garbage (since using uninitialized memory produces undefined behavior.)

忘你却要生生世世 2024-11-23 07:55:15

呃……是的,记忆丢失了。当然,它会丢失,因为您“遗漏了dealloc代码”!

当您“遗漏了释放代码”时,您怎么可能期望有人回答您的问题?您问题的本质是您的 dealloc 代码是否正确。然后你决定把它排除在外?

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

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

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

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

Er... Yes, the memory is lost. Of course, it is lost, since you "left out dealloc code"!

How could you possibly expect anyone to answer your question when you "left out dealloc code"? The very essence of your question is whether your dealloc code is correct or not. And you decided to leave it out?

On top of that, there quite a few thing that make little sense in your code. What is

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

supposed to mean? Why are you typedefing struct ModelArray as Model? In fact, your code will not even compile, since Model * is used inside the struct, where it is not declared yet. You also use ModelArray type in your code, while in reality there's no such type. You have struct ModelArray, but not just ModelArray. The code you posted is not real code. Post real code, please. (Apparently it was supposed to be typedef struct ModelArray { ... } ModelArray; with Model defined elsewhere.)

Finally, as an unrelated note, // comments is a C99 feature. In C99 the function return type cannot be omitted (no "implicit int" rule in C99), meaning that you have to declare your main function as int main.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文