1

在我的大学里,我们被要求创建一个分配所有空闲内存的程序。所以我认为创建一个无限循环并分配内存而不释放它必须消耗计算机的所有可用内存。但是,由于我没有释放内存,因此必须存在巨大的内存泄漏。

所以我写了一个简单的程序,但是当我用 valgrind 检查它时没有内存泄漏。没有任何。没有直接没有间接泄漏。

请告诉我为什么。这是我的程序:

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

int main()
{
    int i,kb=0,mb=0;
    char *some;
    while(1) {
        for(i=0;i<1024;i++)
        {
            // Allocating memory one kilobyte a time.
            some = (char*) malloc(1024);
            if(some == NULL)
            {
                exit(EXIT_FAILURE);
            }
            kb++;
        }
        // Displaying no. of mbs that have been allocated at each mb
        mb++;
        printf("%d mb\n",mb);
    }
    return 0;
}
4

4 回答 4

0

首先想到的是分配已经被优化掉——通常是完全或者推送到堆栈存储。在这种情况下,完全删除它会更好。

您通常通过阅读生成的程序集来证明或反驳这一点。

于 2013-05-08T08:59:19.453 回答
0

当我运行它时 - valgrind 发现问题:

==3335==
==3335== HEAP SUMMARY:
==3335==     in use at exit: 2,271,338,496 bytes in 2,218,104 blocks
==3335==   total heap usage: 2,218,105 allocs, 0 frees, 2,271,338,496 bytes allocated
==3335== 
==3335== 
==3335==     Valgrind's memory management: out of memory:
==3335==        newSuperblock's request for 8876032 bytes failed.
==3335==        3116339200 bytes have already been allocated.
==3335==     Valgrind cannot continue.  Sorry.
==3335== 
==3335==     There are several possible reasons for this.
==3335==     - You have some kind of memory limit in place.  Look at the
==3335==       output of 'ulimit -a'.  Is there a limit on the size of
==3335==       virtual memory or address space?
==3335==     - You have run out of swap space.`

即使使用 O2 O3 也不能消除该错误。是完整的样本吗?

更新

该标志不会改变输出,但如果我在崩溃前中断程序,valgrind 会显示下一个:

^C1890 mb
==3286== 
==3286== HEAP SUMMARY:
==3286==     in use at exit: 1,981,808,640 bytes in 1,935,360 blocks
==3286==   total heap usage: 1,935,360 allocs, 0 frees, 1,981,808,640 bytes allocated
==3286== 
==3286== 276,480 bytes in 270 blocks are possibly lost in loss record 2 of 3
==3286==    at 0x402BE68: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==3286==    by 0x8048472: main (mem_test.c:13)
==3286== 
==3286== 1,981,530,112 bytes in 1,935,088 blocks are definitely lost in loss record 3 of 3
==3286==    at 0x402BE68: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==3286==    by 0x8048472: main (mem_test.c:13)
==3286== 
==3286== LEAK SUMMARY:
==3286==    definitely lost: 1,981,530,112 bytes in 1,935,088 blocks
==3286==    indirectly lost: 0 bytes in 0 blocks
==3286==      possibly lost: 276,480 bytes in 270 blocks
==3286==    still reachable: 2,048 bytes in 2 blocks
==3286==         suppressed: 0 bytes in 0 blocks
==3286== Reachable blocks (those to which a pointer was found) are not shown.
==3286== To see them, rerun with: --leak-check=full --show-reachable=yes
==3286== 
==3286== For counts of detected and suppressed errors, rerun with: -v
==3286== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
于 2013-05-08T09:56:10.470 回答
0

替换some = (char*) malloc(1024);为:some = new char[1024]; 如果您至少有那么多可用内存,它将在 2000MB 时失败。但是,如果您在 Win32 环境中运行它,这不会分配计算机中的所有可用内存,因为每个进程有 2GB 的限制,所以在这种情况下,您将需要另一种方法。

于 2013-05-06T20:20:15.847 回答
0

在 Linux 下,内核不限制分配,而是限制内存的有效使用。(见https://www.kernel.org/doc/Documentation/vm/overcommit-accounting

$ echo 2 > /proc/sys/vm/overcommit_memory

应该禁用它,否则如果您使用 0 填充分配的内存,您的代码应该按预期运行:

some = (char*) malloc(1024);
if(some == NULL) {
   exit(EXIT_FAILURE);
}
memset(some, 0, 1024);
kb++;
于 2014-06-07T08:12:20.460 回答