C程序内存使用 - 报告的内存多于分配的内存

时间:2011-08-24 14:35:03

标签: c memory

我有以下代码:

int main()
{
   char * str1 = (char*)malloc(101 * sizeof(char));
   for (int i=0; i<100; i++)
   {
      str1[i] = 'b';
   }
   str1[100] = 0;

   char * str2 = (char*)malloc(1001 * sizeof(char));
   for (int i=0; i<1000; i++)
   {
      str2[i] = 'a';
   }
   str2[1000] = 0;


   for (int i=0; i<7000; i++)
   {
      char * tmp = str2;
      str2 = (char*) malloc((strlen(str2) + strlen(str1) + 1) * sizeof(char));
      sprintf(str2, "%s%s", tmp, str1);
      free(tmp);
   }

   free(str1);
   free(str2);
}

运行时,任务管理器报告以下内存使用情况: 该计划的开头 - 1056K, 该计划结束 - 17,748K

据我所知,没有内存泄漏,我编译它没有调试符号(发布模式)。

为什么会出现这种情况的任何想法?

3 个答案:

答案 0 :(得分:10)

我认为这是因为free不必将内存返回给操作系统。它只是将它返回到空闲池,从malloc可以分配到空闲池。

答案 1 :(得分:3)

这可能是malloc如何从可用的内存池中选择以满足malloc的工件。此外,像TaskManager和top(用于unix)这样的工具在提供进程使用的实际内存的指示方面是出了名的。每当我的一位客户给我一个最高产量并告诉我我的过程正在泄漏时,我感到畏缩,因为现在我必须证明它不是。

答案 2 :(得分:1)

malloc是C标准库提供的内存管理功能。当您的程序调用malloc时,它不直接从操作系统分配内存。 Malloc实现通常具有一个存储池,它们将它们分割成块以满足分配请求。当您免费拨打电话时,您只会将内存块恢复到此内存池。

对malloc的重复调用最终将从标准库管理的内存池中分配所有内存。此时,需要进行系统调用以从操作系统获取更多内存。在linux上这是brk系统调用,毫无疑问在Windows上类似。

Windows中的任务管理器或Linux中的 top 将报告操作系统为您的进程分配的内存量。这通常会超过程序通过malloc分配的内存量。

如果你在linux上追踪一个程序,你可以看到正在制作这些malloc和brk调用

ltrace -S <some program>
malloc(65536 <unfinished ...>
SYS_brk(NULL)                = 0x2584000
SYS_brk(0x25b5000)           = 0x25b5000
SYS_brk(NULL)                = 0x25b5000
<... malloc resumed> )       = 0x2584010

在此示例中,我们尝试使用malloc(65536),但malloc系统没有足够的可用内存来满足此请求。因此它调用brk()系统调用以从操作系统获取更多内存。在此调用完成后,它可以恢复malloc调用并为程序提供它所请求的内存。