Search code examples
cmallocrealloc

Why won't realloc work in this example?


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


Solution

  • 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.