您可以使用
valgrind,它是一种针对 Linux 和其他类 UNIX 操作系统的内存调试工具,可查找内存泄漏和无效内存访问。当我将此代码通过 valgrind 运行时,输出如下:
[dbush@db-centos7 ~]$ valgrind ./x1
==3406== Memcheck, a memory error detector
==3406== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==3406== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==3406== Command: ./x1
==3406==
left: 4, right: 12, sum: 69
==3406==
==3406== HEAP SUMMARY:
==3406== in use at exit: 300 bytes in 25 blocks
==3406== total heap usage: 49 allocs, 24 frees, 588 bytes allocated
==3406==
==3406== LEAK SUMMARY:
==3406== definitely lost: 300 bytes in 25 blocks
==3406== indirectly lost: 0 bytes in 0 blocks
==3406== possibly lost: 0 bytes in 0 blocks
==3406== still reachable: 0 bytes in 0 blocks
==3406== suppressed: 0 bytes in 0 blocks
==3406== Rerun with --leak-check=full to see details of leaked memory
==3406==
==3406== For counts of detected and suppressed errors, rerun with: -v
==3406== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
那么你有一些内存泄漏问题。现在,让我们传递--leak-check=full
选项来查看这些内存泄漏的确切位置:
==11531== Memcheck, a memory error detector
==11531== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==11531== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==11531== Command: ./x1
==11531==
left: 4, right: 12, sum: 69
==11531==
==11531== HEAP SUMMARY:
==11531== in use at exit: 300 bytes in 25 blocks
==11531== total heap usage: 49 allocs, 24 frees, 588 bytes allocated
==11531==
==11531== 12 bytes in 1 blocks are definitely lost in loss record 1 of 25
==11531== at 0x4C29EA3: malloc (vg_replace_malloc.c:309)
==11531== by 0x4007A8: max_subarray (x1.c:49)
==11531== by 0x400931: main (x1.c:73)
==11531==
==11531== 12 bytes in 1 blocks are definitely lost in loss record 2 of 25
==11531== at 0x4C29EA3: malloc (vg_replace_malloc.c:309)
==11531== by 0x4007B6: max_subarray (x1.c:50)
==11531== by 0x400931: main (x1.c:73)
==11531==
==11531== 12 bytes in 1 blocks are definitely lost in loss record 3 of 25
==11531== at 0x4C29EA3: malloc (vg_replace_malloc.c:309)
==11531== by 0x4007A8: max_subarray (x1.c:49)
==11531== by 0x4007CE: max_subarray (x1.c:51)
==11531== by 0x400931: main (x1.c:73)
==11531==
==11531== 12 bytes in 1 blocks are definitely lost in loss record 4 of 25
==11531== at 0x4C29EA3: malloc (vg_replace_malloc.c:309)
==11531== by 0x4007B6: max_subarray (x1.c:50)
==11531== by 0x4007CE: max_subarray (x1.c:51)
==11531== by 0x400931: main (x1.c:73)
==11531==
==11531== 12 bytes in 1 blocks are definitely lost in loss record 5 of 25
==11531== at 0x4C29EA3: malloc (vg_replace_malloc.c:309)
==11531== by 0x4007A8: max_subarray (x1.c:49)
==11531== by 0x4007CE: max_subarray (x1.c:51)
==11531== by 0x4007CE: max_subarray (x1.c:51)
==11531== by 0x400931: main (x1.c:73)
==11531==
==11531== 12 bytes in 1 blocks are definitely lost in loss record 6 of 25
==11531== at 0x4C29EA3: malloc (vg_replace_malloc.c:309)
==11531== by 0x4007B6: max_subarray (x1.c:50)
==11531== by 0x4007CE: max_subarray (x1.c:51)
==11531== by 0x4007CE: max_subarray (x1.c:51)
==11531== by 0x400931: main (x1.c:73)
==11531==
==11531== 12 bytes in 1 blocks are definitely lost in loss record 7 of 25
==11531== at 0x4C29EA3: malloc (vg_replace_malloc.c:309)
==11531== by 0x4007A8: max_subarray (x1.c:49)
==11531== by 0x4007CE: max_subarray (x1.c:51)
==11531== by 0x4007CE: max_subarray (x1.c:51)
==11531== by 0x4007CE: max_subarray (x1.c:51)
==11531== by 0x400931: main (x1.c:73)
==11531==
==11531== 12 bytes in 1 blocks are definitely lost in loss record 8 of 25
==11531== at 0x4C29EA3: malloc (vg_replace_malloc.c:309)
==11531== by 0x4007B6: max_subarray (x1.c:50)
==11531== by 0x4007CE: max_subarray (x1.c:51)
==11531== by 0x4007CE: max_subarray (x1.c:51)
==11531== by 0x4007CE: max_subarray (x1.c:51)
==11531== by 0x400931: main (x1.c:73)
==11531==
==11531== 12 bytes in 1 blocks are definitely lost in loss record 9 of 25
==11531== at 0x4C29EA3: malloc (vg_replace_malloc.c:309)
==11531== by 0x4007A8: max_subarray (x1.c:49)
==11531== by 0x4007E9: max_subarray (x1.c:52)
==11531== by 0x4007CE: max_subarray (x1.c:51)
==11531== by 0x4007CE: max_subarray (x1.c:51)
==11531== by 0x400931: main (x1.c:73)
==11531==
==11531== 12 bytes in 1 blocks are definitely lost in loss record 10 of 25
==11531== at 0x4C29EA3: malloc (vg_replace_malloc.c:309)
==11531== by 0x4007B6: max_subarray (x1.c:50)
==11531== by 0x4007E9: max_subarray (x1.c:52)
==11531== by 0x4007CE: max_subarray (x1.c:51)
==11531== by 0x4007CE: max_subarray (x1.c:51)
==11531== by 0x400931: main (x1.c:73)
==11531==
==11531== 12 bytes in 1 blocks are definitely lost in loss record 11 of 25
==11531== at 0x4C29EA3: malloc (vg_replace_malloc.c:309)
==11531== by 0x4007A8: max_subarray (x1.c:49)
==11531== by 0x4007E9: max_subarray (x1.c:52)
==11531== by 0x4007CE: max_subarray (x1.c:51)
==11531== by 0x400931: main (x1.c:73)
==11531==
==11531== 12 bytes in 1 blocks are definitely lost in loss record 12 of 25
==11531== at 0x4C29EA3: malloc (vg_replace_malloc.c:309)
==11531== by 0x4007B6: max_subarray (x1.c:50)
==11531== by 0x4007E9: max_subarray (x1.c:52)
==11531== by 0x4007CE: max_subarray (x1.c:51)
==11531== by 0x400931: main (x1.c:73)
==11531==
==11531== 12 bytes in 1 blocks are definitely lost in loss record 13 of 25
==11531== at 0x4C29EA3: malloc (vg_replace_malloc.c:309)
==11531== by 0x4007A8: max_subarray (x1.c:49)
==11531== by 0x4007CE: max_subarray (x1.c:51)
==11531== by 0x4007E9: max_subarray (x1.c:52)
==11531== by 0x4007CE: max_subarray (x1.c:51)
==11531== by 0x400931: main (x1.c:73)
==11531==
==11531== 12 bytes in 1 blocks are definitely lost in loss record 14 of 25
==11531== at 0x4C29EA3: malloc (vg_replace_malloc.c:309)
==11531== by 0x4007B6: max_subarray (x1.c:50)
==11531== by 0x4007CE: max_subarray (x1.c:51)
==11531== by 0x4007E9: max_subarray (x1.c:52)
==11531== by 0x4007CE: max_subarray (x1.c:51)
==11531== by 0x400931: main (x1.c:73)
==11531==
==11531== 12 bytes in 1 blocks are definitely lost in loss record 15 of 25
==11531== at 0x4C29EA3: malloc (vg_replace_malloc.c:309)
==11531== by 0x4007A8: max_subarray (x1.c:49)
==11531== by 0x4007E9: max_subarray (x1.c:52)
==11531== by 0x400931: main (x1.c:73)
==11531==
==11531== 12 bytes in 1 blocks are definitely lost in loss record 16 of 25
==11531== at 0x4C29EA3: malloc (vg_replace_malloc.c:309)
==11531== by 0x4007B6: max_subarray (x1.c:50)
==11531== by 0x4007E9: max_subarray (x1.c:52)
==11531== by 0x400931: main (x1.c:73)
==11531==
==11531== 12 bytes in 1 blocks are definitely lost in loss record 17 of 25
==11531== at 0x4C29EA3: malloc (vg_replace_malloc.c:309)
==11531== by 0x4007A8: max_subarray (x1.c:49)
==11531== by 0x4007CE: max_subarray (x1.c:51)
==11531== by 0x4007E9: max_subarray (x1.c:52)
==11531== by 0x400931: main (x1.c:73)
==11531==
==11531== 12 bytes in 1 blocks are definitely lost in loss record 18 of 25
==11531== at 0x4C29EA3: malloc (vg_replace_malloc.c:309)
==11531== by 0x4007B6: max_subarray (x1.c:50)
==11531== by 0x4007CE: max_subarray (x1.c:51)
==11531== by 0x4007E9: max_subarray (x1.c:52)
==11531== by 0x400931: main (x1.c:73)
==11531==
==11531== 12 bytes in 1 blocks are definitely lost in loss record 19 of 25
==11531== at 0x4C29EA3: malloc (vg_replace_malloc.c:309)
==11531== by 0x4007A8: max_subarray (x1.c:49)
==11531== by 0x4007CE: max_subarray (x1.c:51)
==11531== by 0x4007CE: max_subarray (x1.c:51)
==11531== by 0x4007E9: max_subarray (x1.c:52)
==11531== by 0x400931: main (x1.c:73)
==11531==
==11531== 12 bytes in 1 blocks are definitely lost in loss record 20 of 25
==11531== at 0x4C29EA3: malloc (vg_replace_malloc.c:309)
==11531== by 0x4007B6: max_subarray (x1.c:50)
==11531== by 0x4007CE: max_subarray (x1.c:51)
==11531== by 0x4007CE: max_subarray (x1.c:51)
==11531== by 0x4007E9: max_subarray (x1.c:52)
==11531== by 0x400931: main (x1.c:73)
==11531==
==11531== 12 bytes in 1 blocks are definitely lost in loss record 21 of 25
==11531== at 0x4C29EA3: malloc (vg_replace_malloc.c:309)
==11531== by 0x4007A8: max_subarray (x1.c:49)
==11531== by 0x4007E9: max_subarray (x1.c:52)
==11531== by 0x4007E9: max_subarray (x1.c:52)
==11531== by 0x400931: main (x1.c:73)
==11531==
==11531== 12 bytes in 1 blocks are definitely lost in loss record 22 of 25
==11531== at 0x4C29EA3: malloc (vg_replace_malloc.c:309)
==11531== by 0x4007B6: max_subarray (x1.c:50)
==11531== by 0x4007E9: max_subarray (x1.c:52)
==11531== by 0x4007E9: max_subarray (x1.c:52)
==11531== by 0x400931: main (x1.c:73)
==11531==
==11531== 12 bytes in 1 blocks are definitely lost in loss record 23 of 25
==11531== at 0x4C29EA3: malloc (vg_replace_malloc.c:309)
==11531== by 0x4007A8: max_subarray (x1.c:49)
==11531== by 0x4007CE: max_subarray (x1.c:51)
==11531== by 0x4007E9: max_subarray (x1.c:52)
==11531== by 0x4007E9: max_subarray (x1.c:52)
==11531== by 0x400931: main (x1.c:73)
==11531==
==11531== 12 bytes in 1 blocks are definitely lost in loss record 24 of 25
==11531== at 0x4C29EA3: malloc (vg_replace_malloc.c:309)
==11531== by 0x4007B6: max_subarray (x1.c:50)
==11531== by 0x4007CE: max_subarray (x1.c:51)
==11531== by 0x4007E9: max_subarray (x1.c:52)
==11531== by 0x4007E9: max_subarray (x1.c:52)
==11531== by 0x400931: main (x1.c:73)
==11531==
==11531== 12 bytes in 1 blocks are definitely lost in loss record 25 of 25
==11531== at 0x4C29EA3: malloc (vg_replace_malloc.c:309)
==11531== by 0x40065B: max_crossing_subarray (x1.c:13)
==11531== by 0x400802: max_subarray (x1.c:53)
==11531== by 0x400931: main (x1.c:73)
==11531==
==11531== LEAK SUMMARY:
==11531== definitely lost: 300 bytes in 25 blocks
==11531== indirectly lost: 0 bytes in 0 blocks
==11531== possibly lost: 0 bytes in 0 blocks
==11531== still reachable: 0 bytes in 0 blocks
==11531== suppressed: 0 bytes in 0 blocks
==11531==
==11531== For counts of detected and suppressed errors, rerun with: -v
==11531== ERROR SUMMARY: 25 errors from 25 contexts (suppressed: 0 from 0)
这些泄漏主要来自以下两行代码:
struct Interval * left = malloc(sizeof(struct Interval));
struct Interval * right = malloc(sizeof(struct Interval));
如果我们看一下接下来的两行,就会明白原因:
left = max_subarray(A, low, mid);
right = max_subarray(A, mid+1, high);
在将分配的内存地址赋给这些指针后,您立即使用其他值覆盖这些地址,导致泄漏。通过摆脱malloc
调用并使用函数调用的结果进行初始化来解决此问题:
struct Interval * left = max_subarray(A, low, mid);
struct Interval * right = max_subarray(A, mid+1, high);
最后一个是在
max_crossing_subarray
中。
struct Interval * crossing = malloc(sizeof(struct Interval));
这个指针是从函数返回的,因此我们需要查看缺少的free
在哪里。经过一些查找,我们发现它是从max_subarray
调用的,最终将其作为result
返回给main
:
struct Interval * result = max_subarray(A, 0, 13-1);
printf("left: %i, right: %i, sum: %i\n", result->max_left, result->max_right, result->sum);
return 0;
但是正如你所看到的,这里没有调用free
,因此让我们添加它:
struct Interval * result = max_subarray(A, 0, 13-1);
printf("left: %i, right: %i, sum: %i\n", result->max_left, result->max_right, result->sum);
free(result);
return 0;
在进行上述修复后,我们将再次运行valgrind:
==11736== Memcheck, a memory error detector
==11736== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==11736== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==11736== Command: ./x1
==11736==
left: 4, right: 12, sum: 69
==11736==
==11736== HEAP SUMMARY:
==11736== in use at exit: 0 bytes in 0 blocks
==11736== total heap usage: 25 allocs, 25 frees, 300 bytes allocated
==11736==
==11736== All heap blocks were freed -- no leaks are possible
==11736==
==11736== For counts of detected and suppressed errors, rerun with: -v
==11736== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
泄漏问题已经解决。
left
和right
分配内存,然后立即通过将其他东西分配给这些变量来丢弃这些内存分配。因此,这些内存被浪费掉了,之后就不知道free
实际上释放了什么。 - Sami Kuhmonenfloor((low+high)/2);
而不是(low+high)/2;
? - chux - Reinstate Monica(low+high)/2
不保证返回整数,尽管我认为隐式转换不会造成问题。 - Ivor Denham-Dysonint low
和int high
,(low+high)/2
返回一个int
。没有强制转换。商的小数部分被丢弃 - 向零舍入。 - chux - Reinstate Monica