重新分配2d数组 - valgrind错误

时间:2014-09-12 18:45:42

标签: c pointers malloc valgrind realloc

我在尝试重新分配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)

1 个答案:

答案 0 :(得分:0)

realloc_2d_int中,您在重新分配的内存中循环显示xlen个指针,但如果旧xlen不等于新xlen,则不要有那么多指向realloc的指针。让我们说旧的是3,新的是4。索引3处的指针对于传递给realloc无效。你需要:

  • 如果old大于new,请在执行第一次realloc之前释放末尾的额外旧指针,这样就不会泄漏内存。
  • 如果new大于旧版,则会在数组末尾添加malloc个附加指针,而不是尝试realloc

这可能意味着您需要将旧的xlen传递给此函数。