简体   繁体   English

Valgrind Memory 泄漏,无效的免费()

[英]Valgrind Memory Leaks, Invalid free()

typedef struct {
   int **a;
   int **b;
   int **c;
   int i;
} test_t;

test_t *create(int i) {
    test_t *test = malloc(i * sizeof(test_t));

    test->i = i;

    test->c = malloc(i * sizeof(int *));
    for (int j = 0; j < i; ++j) {
        test->c[j] = malloc(sizeof(int *));
    }

    test->a = malloc(sizeof(int *));
    test->a = &(test->c[0]);
    test->b = malloc(sizeof(int *));
    test->b = &(test->c[0]);
    return test;
}

void delete(test_t *test) {
    free(test->a);
    free(test->b);
    for (int i = 0; i < test->i; ++i)
        free(test->c[i]);
    free(test->c);
    free(test);
}

int main() {
    test_t *test;

    test = create(3);

    delete(test);

    return 0;
}

What's wrong with this code?这段代码有什么问题?

When I run Valgrind, I get 5 errors and some memory leaks.当我运行 Valgrind 时,我得到 5 个错误和一些 memory 泄漏。

I don't see any memory leak, do you?我没有看到任何 memory 泄漏,是吗?

I get errors like:我收到如下错误:

Invalid free() / delete / delete[] / realloc()
Address 0x4a380e0 is 0 bytes inside a block of size 24 free'd
Block was alloc'd at
Invalid read of size 8

Could anybody help me with that, please?请问有人可以帮我吗?

PS The code works fine, but it has memory leaks, so it doesn't. PS 代码工作正常,但它有 memory 泄漏,所以它没有。

Eyeballing it...目不转睛...

    test->a = malloc(sizeof(int *));
    test->a = &(test->c[0]);
    test->b = malloc(sizeof(int *));
    test->b = &(test->c[0]);

Since test->a and test->b are immediately reassigned, the mallocs have no effect except to leak memory.由于test->atest->b立即重新分配,因此 malloc 没有任何作用,除了泄漏 memory。 The above should be simply...以上应该很简单...

    test->a = &(test->c[0]);
    test->b = &(test->c[0]);

With that the rule of thumb that the number of mallocs should equal the number of frees works.有了这个经验法则,mallocs 的数量应该等于 frees 的数量。 Three mallocs, one in a loop.三个 malloc,一个循环。 Three frees, one in a loop.三个释放,一个循环。

void delete(test_t *test) {
    for (int i = 0; i < test->i; i++) {
        free(test->c[i]);
    }
    free(test->c);
    free(test);
    test->a = NULL;
    test->b = NULL;
}

test->a and test->b should not be freed as they are borrowing test->c[0] 's memory. test->atest->b不应被释放,因为它们正在借用test->c[0]的 memory。 We need too avoid freeing it twice.我们也需要避免两次释放它。 Since that borrowed memory is invalid and can no longer be used, we set it to NULL as a precaution.既然借来的memory是无效的,不能再用了,我们把它设置为NULL万一。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM