Reputation: 3
My professor gave us an "assignment" to find why realloc()
won't work in this specific example.
I tried searching this site and I think that it won't work because there is no real way to determine the size of a memory block allocated with malloc()
so realloc()
doesn't know the new size of the memory block that it needs to reallocate.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
int main ()
{
MEMORYSTATUS memInfo;
memInfo.dwLength = sizeof(MEMORYSTATUS);
GlobalMemoryStatus(&memInfo);
double slobodno = memInfo.dwAvailVirtual/1024./1024.;
printf("%g MB\n",slobodno);
int br=0,i,j;
char **imena,*ime,*temp,*bbb=NULL;
imena=(char**) malloc(sizeof(char*)*(br+1));
while(1)
{
printf("Unesite ime: ");
ime=(char*) malloc(sizeof(char)*4000000);
gets(ime);
printf("%u\n", strlen(ime));
ime=(char*) realloc(ime,strlen(ime)+1);
GlobalMemoryStatus(&memInfo);
slobodno = memInfo.dwAvailVirtual/1024./1024.;
printf("%g MB\n",slobodno);
if (strcmp(ime,".")==0)
{free(ime);free(imena[br]);break;}
imena[br++]=ime;
imena=(char**) realloc(imena,sizeof(char*)*(br+1));
}
for (i=0;i<br-1;i++)
for (j=i+1;j<br;j++)
if (strcmp(imena[i],imena[j])>0)
{
temp=imena[i];
imena[i]=imena[j];
imena[j]=temp;
}
//ovde ide sortiranje
for (i=0;i<br;i++)
printf("%s\n",imena[i]);
for(i=0;i<br;i++)
free(imena[i]);
free(imena);
return 0;
}
Note: Professor added the lines for printing out the available memory so we can see that realloc()
doesn't work. Every new string we enter just takes up sizeof(char)+4000000
bytes and can't be reallocated. I'm trying to find out why. Thanks in advance
Upvotes: 0
Views: 917
Reputation: 15758
The problem is not that realloc doesn't know the size of the original block. Even though that information is not available for us programmers, it is required to be available to realloc (even if the block was allocated with malloc or calloc).
The line
ime=(char*) realloc(ime,strlen(ime)+1);
looks like it is shrinking the previously allocated block to fit the contents exactly, but there is no requirement that is actually shrinks the block of memory and makes the remainder available again for a new allocation.
Edit
Another thing I just thought of: The shrinking with realloc might work OK, but the memory is not returned by the runtime library to the OS because the library keeps it around for a next allocation. Only, the next allocation is for such a large block that it does not fit the memory freed up with realloc.
Upvotes: 0
Reputation: 2970
realloc
doesn't free memory. These functions work with a big block of memory (called a "heap") and carve chunks out when you call realloc
/malloc
/calloc
. If you need more memory than is in the heap at the moment, then the heap is expanded by asking the operating system for more memory.
When you call realloc
to make a memory block smaller, all that happens is that the memory you don't need any more is made available for *alloc
to hand out again on a different request. Neither realloc
nor free
ever shrink the heap to return memory back to the operating system. (If you need that to happen, you need to call the operating system's native memory allocation procedures, such as VirtualAlloc
on Windows.)
Upvotes: 0
Reputation: 9480
I have a feeling that it has something to do with the page sizes on Windows. For example, if you change 4000000 to 400000, you can see that the memory can be re-used.
I think that allocating 4000000 forces Windows to use "huge" page sizes (of 4MB) and for some (unknown to me) reason, realloc doesn't work on them in the way that you would expect (i.e. making unused memory available for other allocations).
This seems to be related to Realloc() does not correctly free memory in Windows, which mentions VirutalAlloc, but I'm not sure it clarifies the exact reason that realloc doesn't work.
Upvotes: 3
Reputation: 2970
From MSDN:
The
memblock
argument points to the beginning of the memory block. Ifmemblock
isNULL
,realloc
behaves the same way asmalloc
and allocates a new block ofsize
bytes.
So the line ime=(char*) realloc(NULL,sizeof(char)*4000000);
just malloc
's new memory each time.
Upvotes: 0