【问题标题】:*** glibc detected *** ./m: free(): invalid next size (fast) on trying to free heap memory [duplicate]*** 检测到 glibc *** ./m: free(): 在尝试释放堆内存时下一个大小无效(快速)[重复]
【发布时间】:2013-02-05 22:45:15
【问题描述】:

我有一个小代码,它在堆上分配一些内存,然后在使用后尝试释放它。 内存映射出现此错误。

代码是 ::

void merge(int *arr, int start, int mid, int end)
{
     int i = 0, j = 0, k = 0, tmp1 = 0, siz = 0;
     int *pt = NULL;
     j = start, k = mid+1, tmp1 = start;

     siz = (end - start) + 1;

     if ((pt = malloc(siz * sizeof(int))) == NULL) /* line 32 */
     {
         printf("\n ERROR Aloocating mem \n");
         return;
     }

     while (j <= mid && k <= end)
     {
        if (arr[j] <= arr[k])
        {
          pt[tmp1] = arr[j];
          ++j;
          ++tmp1;
        }
        if (arr[j] > arr[k])
        {
          pt[tmp1] = arr[k]; /* line 48 */
          ++k;
          ++tmp1;
        }

      } 
       while (j <= mid)
       {
          pt[tmp1] = arr[j]; /* line 56 */
          ++tmp1;
          ++j;
       }
        while (k <= end)
        {
           pt[tmp1] = arr[k];
           ++k;
           ++tmp1;
        }

        for (i = 0; i < siz; i++)
        {
           arr[end] = pt[end]; /* line 69 */
           --end;
        }   

        free(pt);   
    }   

我得到的错误是::

*** glibc detected *** ./m: free(): invalid next size (fast): 0x0940c008 ***
======= Backtrace: =========
/lib/tls/i686/cmov/libc.so.6(+0x6b161)[0x213161]
/lib/tls/i686/cmov/libc.so.6(+0x6c9b8)[0x2149b8]
/lib/tls/i686/cmov/libc.so.6(cfree+0x6d)[0x217a9d]
./m[0x80486d8]
./m[0x8048562]
./m[0x8048526]
./m[0x8048542]
./m[0x804874b]
/lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe6)[0x1bebd6]
./m[0x8048441]
======= Memory map: ========
001a8000-002fb000 r-xp 00000000 08:01 1535       /lib/tls/i686/cmov/libc-2.11.1.so
002fb000-002fd000 r--p 00153000 08:01 1535       /lib/tls/i686/cmov/libc-2.11.1.so
002fd000-002fe000 rw-p 00155000 08:01 1535       /lib/tls/i686/cmov/libc-2.11.1.so
002fe000-00301000 rw-p 00000000 00:00 0 
00483000-0049e000 r-xp 00000000 08:01 1712996    /lib/ld-2.11.1.so
0049e000-0049f000 r--p 0001a000 08:01 1712996    /lib/ld-2.11.1.so
0049f000-004a0000 rw-p 0001b000 08:01 1712996    /lib/ld-2.11.1.so
007f8000-00815000 r-xp 00000000 08:01 1708381    /lib/libgcc_s.so.1
00815000-00816000 r--p 0001c000 08:01 1708381    /lib/libgcc_s.so.1
00816000-00817000 rw-p 0001d000 08:01 1708381    /lib/libgcc_s.so.1
00b38000-00b39000 r-xp 00000000 00:00 0          [vdso]
08048000-08049000 r-xp 00000000 08:01 1317230    /home/abhi/Desktop/ad/A1/misc/m
08049000-0804a000 r--p 00000000 08:01 1317230    /home/abhi/Desktop/ad/A1/misc/m
0804a000-0804b000 rw-p 00001000 08:01 1317230    /home/abhi/Desktop/ad/A1/misc/m
0940c000-0942d000 rw-p 00000000 00:00 0          [heap]
b7600000-b7621000 rw-p 00000000 00:00 0 
b7621000-b7700000 ---p 00000000 00:00 0 
b777e000-b777f000 rw-p 00000000 00:00 0 
b778c000-b7790000 rw-p 00000000 00:00 0 
bf8b5000-bf8ca000 rw-p 00000000 00:00 0          [stack]
Aborted

我浏览了一些关于 SO 的类似问题的答案,得知这是一个内存错误。

所以我用 valgrind 运行编码并得到以下输出(不是完整的输出)

==4494== 
==4494== Invalid write of size 4
==4494==    at 0x8048650: merge (merge.c:48)
==4494==    by 0x8048561: merge_sort (merge.c:20)
==4494==    by 0x8048525: merge_sort (merge.c:18)
==4494==    by 0x8048541: merge_sort (merge.c:19)
==4494==    by 0x8048766: main (merge.c:89)
==4494==  Address 0x41920ac is 4 bytes after a block of size 8 alloc'd
==4494==    at 0x4023AB8: malloc (vg_replace_malloc.c:207)
==4494==    by 0x80485CB: merge (merge.c:32)
==4494==    by 0x8048561: merge_sort (merge.c:20)
==4494==    by 0x8048525: merge_sort (merge.c:18)
==4494==    by 0x8048541: merge_sort (merge.c:19)
==4494==    by 0x8048766: main (merge.c:89)
==4494== 
==4494== Invalid write of size 4
==4494==    at 0x8048680: merge (merge.c:56)
==4494==    by 0x8048561: merge_sort (merge.c:20)
==4494==    by 0x8048525: merge_sort (merge.c:18)
==4494==    by 0x8048541: merge_sort (merge.c:19)
==4494==    by 0x8048766: main (merge.c:89)
==4494==  Address 0x41920b0 is 8 bytes after a block of size 8 alloc'd
==4494==    at 0x4023AB8: malloc (vg_replace_malloc.c:207)

==4494== Invalid read of size 4
==4494==    at 0x80486D5: merge (merge.c:69)
==4494==    by 0x8048561: merge_sort (merge.c:20)
==4494==    by 0x8048541: merge_sort (merge.c:19)
==4494==    by 0x8048766: main (merge.c:89)
==4494==  Address 0x41920ec is 8 bytes after a block of size 12 alloc'd
==4494==    at 0x4023AB8: malloc (vg_replace_malloc.c:207)
==4494==    by 0x80485CB: merge (merge.c:32)
==4494==    by 0x8048561: merge_sort (merge.c:20)
==4494==    by 0x8048541: merge_sort (merge.c:19)
==4494==    by 0x8048766: main (merge.c:89)

我无法纠正malloc 对我来说很好的问题。我正在分配 siz * sizeof(int) 字节(int 在我的机器上是 4 个字节),然后以 if 数组的形式使用分配的内存。

如果有人指出我正在做的错误并解释原因,将不胜感激。 谢谢

【问题讨论】:

  • 这告诉你,你正在写你分配的缓冲区的范围之外。您应该单步执行您的代码,并确认所有索引都完全符合您的预期。
  • 使用valgrind 并使用gcc -Wall -g 编译您的代码并学习使用调试器。
  • @Bill 请在代码中查看我对行号的编辑

标签: c linux memory-management free glibc


【解决方案1】:

为了扩展 Daniel 正确指出 pt[end] 不正确,假设以下函数调用:

int values[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
merge(values, 4, 5, 6);

merge 中,分配的 pt 足够大,可容纳 (6 - 4) + 1 = 3 ints。 tmp1 设置为 4。 在第 48 行,你写了pt[tmp1] = arr[k],但这是pt[4] = arr[0],你写的是pt之外的内存!

【讨论】:

  • 哦,哇,完全忽略了那条线。我所看到的只是原始初始化为 0。
  • 是的,tmp1 的双重初始化一开始也让我感到震惊。 :)
  • @Bill 感谢比尔指出我犯的错误..
【解决方案2】:

您使用 tmp1 作为索引,并将其初始化为 start 而不是 0。详细说明:

 j = start, k = mid+1, tmp1 = start;

 siz = (end - start) + 1;

 if ((pt = malloc(siz * sizeof(int))) == NULL)

pt 从 0 变为 (end-start) + 1,但您开始使用索引 tmp1 = start 访问它。

tmp1 应该为 0。具体而言,如果 end 为 10,start 为 8,您将分配 3 个字节...并且您不希望 tmp1 索引从 8 开始三元数组!

【讨论】:

  • 感谢 wilsonmuchaelpatrick
【解决方案3】:
arr[end] = pt[end];

访问pt 越界,除非start == 0pt 的最后一个有效索引是 end-start

另外,在

 while (j <= mid && k <= end)
 {
    if (arr[j] <= arr[k])
    {
      pt[tmp1] = arr[j];
      ++j;
      ++tmp1;
    }
    if (arr[j] > arr[k])
    {
      pt[tmp1] = arr[k];
      ++k;
      ++tmp1;
    }

  }

在第二个if 中,j 可以大于mid - 如果它在迭代开始时是== mid - 你最好用else 替换第二个if

【讨论】:

  • 感谢您的回答。我肯定错过了。我的错。我将编辑代码并检查。
猜你喜欢
  • 2012-02-22
  • 1970-01-01
  • 1970-01-01
  • 2012-11-14
  • 2011-04-12
  • 2011-06-26
  • 2017-03-12
  • 2012-05-22
相关资源
最近更新 更多