0

我的教授给了我们一个“作业”来找出为什么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

4 回答 4

3

我感觉它与 Windows 上的页面大小有关。比如把4000000改成400000,可以看到内存是可以重复使用的。

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

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

于 2012-11-07T20:33:01.853 回答
0

来自MSDN

memblock参数指向内存块的开头。If memblockis NULL,realloc行为malloc与分配一个新的size字节块相同。

所以这条线每次都是新的记忆ime=(char*) realloc(NULL,sizeof(char)*4000000);malloc

于 2012-11-07T20:21:32.360 回答
0

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

线

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

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

编辑

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

于 2012-11-07T20:22:39.333 回答
0

realloc不释放内存。这些函数使用一大块内存(称为“堆”)并在您调用realloc/ malloc/时切出块calloc。如果您需要比当前堆中更多的内存,则通过向操作系统请求更多内存来扩展堆。

当您调用realloc以使内存块更小时,所发生的一切就是您不再需要的内存可用于*alloc根据不同的请求再次分发。既realloc不会也free不会收缩堆以将内存返回给操作系统。(如果您需要这样做,您需要调用操作系统的本机内存分配过程,例如VirtualAlloc在 Windows 上。)

于 2012-11-07T20:37:39.267 回答