【问题标题】:alloc and free of 2d arrayalloc 并且没有二维数组
【发布时间】:2016-11-07 19:55:35
【问题描述】:

我制作了 2d array(matrix) + alloc 和 free 函数来管理内存,但效果不佳,valgrind 打印出许多错误和内存丢失的信息。

Alloc: 参数 s 表示矩阵的大小

int** alloc(int s)
{
    int** matrix;
    int i;

    matrix = (int**)malloc(s * sizeof(int*));
    for (i = 0; i < s; i++)
    {
        matrix[i] = calloc(s, sizeof(int));
    }

    return matrix;
}

免费

void matrix_free(int*** matrix, int s)
{
    int i;
    for(i = 0; i < s; i++)
    {
        free(*((matrix)+i));
    }
    free(matrix);

}

瓦尔格林: 很多这样的错误:

Invalid read of size 8
==3767==    at 0x4FAA8D4: buffer_free (in /lib/x86_64-linux-gnu/libc-2.24.so)
==3767==    by 0x4FAA942: __libc_freeres (in /lib/x86_64-linux-gnu/libc-2.24.so)
==3767==    by 0x4A276EC: _vgnU_freeres (in /usr/lib/valgrind/vgpreload_core-amd64-linux.so)
==3767==    by 0x4E73292: __run_exit_handlers (exit.c:98)
==3767==    by 0x4E73339: exit (exit.c:105)
==3767==    by 0x4E593F7: (below main) (libc-start.c:325)
==3767==  Address 0x52000e8 is 168 bytes inside a block of size 552 free'd
==3767==    at 0x4C2DD6B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3767==    by 0x108BBB: matrix_free (m1.c:68)
==3767==    by 0x108B69: main (m1.c:58)
==3767==  Block was alloc'd at
==3767==    at 0x4C2CB3F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3767==    by 0x4EA7F2C: __fopen_internal (iofopen.c:69)
==3767==    by 0x108919: main (m1.c:16)
==3767== 
==3767== 
==3767== HEAP SUMMARY:
==3767==     in use at exit: 36 bytes in 3 blocks
==3767==   total heap usage: 7 allocs, 6 frees, 5,732 bytes allocated
==3767== 
==3767== LEAK SUMMARY:
==3767==    definitely lost: 36 bytes in 3 blocks
==3767==    indirectly lost: 0 bytes in 0 blocks
==3767==      possibly lost: 0 bytes in 0 blocks
==3767==    still reachable: 0 bytes in 0 blocks
==3767==         suppressed: 0 bytes in 0 blocks

【问题讨论】:

  • 请提供minimal reproducible example,包括对可以重现问题的这些函数的调用。
  • 对于初学者int*** matrix 看起来很可疑。该矩阵被分配为int **,但不知何故,免费正在释放int ***。所以请提供一个 MCVE,以便我们在上下文中查看代码,然后我们可以给出明确的答案。
  • matrix_free 看起来不对。你传入一个int***,所以for循环中的frees应该有**取消引用,最后的free应该是free(*matrix);
  • 为什么原来的表示是基于int **指针,而free却突然期待int ***指针?额外的* 是从哪里来的?为什么要转换malloc 的结果(却不转换calloc 的结果)?
  • 这个问题已经被问过很多次了,其中一个人甚至问了一个5d版本。我们真的需要把它写到 SO 文档中。

标签: c arrays matrix alloc


【解决方案1】:

在这种情况下,free 函数不使用指向已分配内存的指针,而是使用指向该指针的指针。

要释放内存,您首先需要获取该指针。

void matrix_free(int*** matrix, int s)
{
    int** m = *matrix;
    int i;
    for(i = 0; i < s; i++)
    {
        free( m[i] );
    }
    free( m );

    *matrix = NULL;
}

此变体还允许您将参数设置为 NULL:

matrix_free( &matrix , s );
assert( matrix == NULL );

【讨论】:

    猜你喜欢
    • 2015-05-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-17
    • 1970-01-01
    • 1970-01-01
    • 2020-07-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多