简体   繁体   中英

C program memory usage - more memory reported than allocated

I have the following code:

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);
}

When running it, task manager reports the following Memory Usage: beginning of the program - 1056K , end of the program - 17,748K

To my knowledge there are no memory leaks and I compiled it without debug symbols (release mode).

Any ideas why this might happen?

I think this is because free doesn't have to return memory to the OS. It simply returns it to the free pool, from where it can be allocated by malloc .

This is probably an artifact of how malloc selects from the available pools of memory to satisfy a malloc. Also, tools like TaskManager and top (for unix) are notoriously bad at providing an indication of actual memory used by a process. Every time one of my customers gives me a top output and tells me my process is leaking, I cringe because now I have to prove that it is not.

malloc is a memory management function provided by the C standard library. When your program calls malloc it is not directly allocating memory from the operating system. Malloc implementations generally have a pool of memory which they carve up into blocks to satisfy allocation requests. When you call free you are only giving your memory block back to this memory pool.

Repeated calls to malloc will eventually allocate all of the memory from the memory pool managed by the standard library. At this point a system call will need to be made to get more memory from the operating system. On linux this is the brk system call, there will no doubt be something similar on Windows.

The Task Manager in Windows, or top in linux, will report the amount of memory that the operating system has allocated to your process. This will normally be more than the amount of memory your program has allocated via malloc.

If you ltrace a program on linux you can see these malloc and brk calls being made

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

In this example we try to malloc(65536), but the malloc system does not have enough free memory to satisfy this request. So it calls the brk() system call to get more memory from the operating system. After this call completes it can resume the malloc call and give the program the memory it requested.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM