我有一个小代码,它在堆上分配一些内存,然后在它使用后尝试释放它。 我在内存映射中遇到了这个错误。
守则是::
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个字节),然后在表格中使用分配的内存。
如果有人指出我正在做的错误并解释原因,我们将不胜感激。 感谢
答案 0 :(得分:5)
为了扩展Daniel正确指出pt[end]
不正确,请假设以下函数调用:
int values[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
merge(values, 4, 5, 6);
在merge
中,pt被分配为足够大(6 - 4)+ 1 = 3 int
s。
tmp1
设置为4。
在第48行,您执行了pt[tmp1] = arr[k]
,但这是pt[4] = arr[0]
,而您正在写pt
以外的内存!
答案 1 :(得分:3)
您使用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个字节......并且您不希望{{1}索引从3元素数组中的8开始!
答案 2 :(得分:2)
arr[end] = pt[end];
除非pt
,否则访问start == 0
越界。 pt
的最后一个有效索引是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
,则最好更换第二个if
1}} else
。