【问题标题】:Reallocating 2d array - valgrind errors重新分配二维数组 - valgrind 错误
【发布时间】:2014-11-07 00:25:24
【问题描述】:

当我尝试重新分配 2d int 数组时,我在一个巨大的应用程序中遇到了总线错误。为了缩小问题的范围,我只使用重新分配生成了一个小代码。问:Valgrind 有点抱怨,但没有崩溃。这些是误报吗?

#include <stdio.h>
#include <stdlib.h>

#define FREE(x)         {free(x);(x)=NULL;}

/* ======================== subroutine for dynamically reallocating 2d int matrix========================== */
int **realloc_2d_int(int **array, int xlen, int ylen)
{
    int i;

    if( (array = (int **) realloc( array,xlen*sizeof(int *)) ) == NULL) ERROR("without enough memory for redefining 2d int array");
    for(i = 0; i < xlen; i++){
        if ( (array[i] = (int *) realloc( array[i],ylen*sizeof(int))) == NULL) ERROR("without enough memory for redefining 2d int matrix array[i]");
    }

    return array;
    }

/* ======================== subroutine for dynamically allocating 2d int matrix========================== */
int **malloc_2d_int(int xlen, int ylen)
{
    int i;
    int **array=NULL;  

    if( (array = (int **) malloc( xlen*sizeof(int *)) ) == NULL) ERROR("without enough     memory for defining 2d int array");
    for(i = 0; i < xlen; i++){
        if ( (array[i] = (int *) malloc( ylen*sizeof(int))) == NULL)  ERROR("without enough       memory for defining 2d int matrix array[i]");
    }

    return array;
}

int main()
{
   int i,**matrix = NULL;
   size_t size = 100, newsize;

   matrix = malloc_2d_int(size,size);

   for(newsize = 2*size; newsize<=100*size; newsize+=size)   
       matrix = realloc_2d_int(matrix,newsize,newsize);

   for(i=0;i<=100*size;i++) FREE(matrix[i]);
   FREE(matrix);

   return 0;
}

编辑:而对应的 Valgrind 错误为:

==18369== Memcheck, a memory error detector
==18369== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==18369== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==18369== Command: ./test_realloc
==18369== 
==18369== Conditional jump or move depends on uninitialised value(s)
==18369==    at 0x4C2CE3B: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==18369==    by 0x40079E: realloc_2d_int (test_realloc.c:44)
==18369==    by 0x4008E6: main (test_realloc.c:75)
==18369== 
==18369== Invalid read of size 8
==18369==    at 0x400919: main (test_realloc.c:77)
==18369==  Address 0x1df0c520 is 0 bytes after a block of size 80,000 alloc'd
==18369==    at 0x4C2CE8E: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==18369==    by 0x400728: realloc_2d_int (test_realloc.c:42)
==18369==    by 0x4008E6: main (test_realloc.c:75)
==18369== 
==18369== Invalid write of size 8
==18369==    at 0x400938: main (test_realloc.c:77)
==18369==  Address 0x1df0c520 is 0 bytes after a block of size 80,000 alloc'd
==18369==    at 0x4C2CE8E: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==18369==    by 0x400728: realloc_2d_int (test_realloc.c:42)
==18369==    by 0x4008E6: main (test_realloc.c:75)
==18369== 
==18369== 
==18369== HEAP SUMMARY:
==18369==     in use at exit: 0 bytes in 0 blocks
==18369==   total heap usage: 505,100 allocs, 505,100 frees, 13,538,040,000 bytes allocated
==18369== 
==18369== All heap blocks were freed -- no leaks are possible
==18369== 
==18369== For counts of detected and suppressed errors, rerun with: -v
==18369== Use --track-origins=yes to see where uninitialised values come from
==18369== ERROR SUMMARY: 9902 errors from 3 contexts (suppressed: 0 from 0)

【问题讨论】:

  • valgrind 给出了什么错误?请将它们包括在问题中。
  • 这不是一个二维数组,而只是一个模拟。可能您无法更改先前存在的代码,但真正的 2D 数组更易于处理,并且您尤其可以避免 2D 仿真这个臭名昭著的问题。
  • 喜欢?当然,如果这就是您所说的,这里并不暗示它是内存中的物理二维数组。如果没有,能否通过示例进一步解释您的推理?

标签: c pointers malloc valgrind realloc


【解决方案1】:

realloc_2d_int 中,您循环遍历重新分配的内存中的xlen 指针,但如果旧的xlen 不等于新的xlen,则您没有那么多指向realloc 的指针。假设旧的为3,新的为4。索引3 处的指针对于传递给realloc 无效。您需要:

  • 如果 old 大于 new,则在执行第一个 realloc 之前释放末尾多余的旧指针,以免内存泄漏。
  • 如果 new 大于 old,则 malloc 在数组末尾添加额外的指针,而不是尝试 realloc 它们。

这可能意味着您需要将旧的和新的xlen 都传递给这个函数。

【讨论】:

  • 这就是问题所在。太棒了!
  • 实际上,也许我对此有点天真,但假设新的总是大于旧的,如果我理解正确,您的解决方案将是:
  • if( (array = (int **) realloc( array,new_xlen*sizeof(int *)) ) == NULL) ERROR("without enough memory for redefining 2d int array"); for(i=old_xlen; i&lt;new_xlen; i++) array[i]= malloc_1d_int(new_ylen); for(i = 0; i &lt; old_xlen; i++){ if ( (array[i] = (int *) realloc( array[i],new_ylen*sizeof(int))) == NULL) ERROR("without enough memory for redefining 2d int matrix array[i]"); }
  • 是的。但如果你不打算为释放而烦恼,你也应该检查以确保new &gt;= old
猜你喜欢
  • 1970-01-01
  • 2021-10-11
  • 2021-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-23
  • 2012-03-27
  • 1970-01-01
相关资源
最近更新 更多