为什么在这个例子中不会重新分配工作?

时间:2012-11-07 20:12:40

标签: c malloc realloc

我的教授给了我们一个“作业”,找出为什么realloc()在这个具体的例子中不起作用。 我尝试搜索这个网站,我认为它不会起作用,因为没有真正的方法来确定用malloc()分配的内存块的大小,因此realloc()不知道新的大小需要重新分配的内存块。

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

注意:教授添加了用于打印可用内存的行,因此我们可以看到realloc()不起作用。我们输入的每个新字符串只占用sizeof(char)+4000000个字节,无法重新分配。我试图找出原因。提前致谢

4 个答案:

答案 0 :(得分:3)

我觉得它与Windows上的页面大小有关。 例如,如果将4000000更改为400000,则可以看到可以重复使用内存。

我认为分配4000000迫使Windows使用“巨大的”页面大小(4MB)和某些(我不知道)的原因,realloc不会以你期望的方式对它们起作用(即制作未使用的内存)可用于其他分配)。

这似乎与提到VirutalAlloc的Realloc() does not correctly free memory in Windows有关,但我不确定它是否说明realloc不起作用的确切原因。

答案 1 :(得分:0)

来自MSDN

  

memblock参数指向内存块的开头。如果memblockNULL,则realloc的行为与malloc相同,并分配一个新的size字节块。

所以ime=(char*) realloc(NULL,sizeof(char)*4000000);行每次只有malloc的新记忆。

答案 2 :(得分:0)

问题不在于realloc不知道原始块的大小。即使我们的程序员无法获得该信息,也需要重新分配(即使该块使用malloc或calloc分配)。

该行

ime=(char*) realloc(ime,strlen(ime)+1);

看起来正在缩小先前分配的块以准确地拟合内容,但是没有要求实际上缩小内存块并使剩余部分再次可用于新分配。

修改

我刚才想到的另一件事:使用realloc缩小可能会正常工作,但运行时库不会将内存返回给操作系统,因为库会保留它以供下次分配。 只是,下一个分配是针对这么大的块,它不适合使用realloc释放的内存。

答案 3 :(得分:0)

realloc没有释放内存。当您调用realloc / malloc / calloc时,这些函数可以使用大块内存(称为&#34;堆&#34;)并刻出块。如果此时需要的内存多于堆中的内存,则通过向操作系统请求更多内存来扩展堆。

当您致电realloc以缩小内存块时,所发生的一切就是*alloc可以使用不再需要的内存再次发送给不同的内存块请求。 reallocfree都没有缩小堆以将内存返回给操作系统。 (如果需要这样做,则需要调用操作系统的本机内存分配过程,例如Windows上的VirtualAlloc。)