试图理解realloc和malloc函数是如何工作的

时间:2017-10-14 23:39:25

标签: c malloc realloc

很抱歉,如果问题是基本的,但我不明白为什么如果我不添加" + 1"该程序不打印所有字母

  

a = realloc(a,sizeof(char)*(i + 1));

也在这里

  

*(a + i)= letra;

" a"的位置?每次通过都变得更大? 我想情况并非如此,但我不太确定。

#include <stdio.h>
#include <stdlib.h>

char *copiarFrase();

int main()
{
    char *frase;
    frase = copiarFrase();
    printf("Frase: %s", frase);
    free(frase);
    return 0;
}


char *copiarFrase()
{
    FILE *archivo;
    char letra;
    char *a;
    int i = 0;
    archivo = fopen("frases.txt", "r");
    a = malloc(sizeof(char));
    letra = fgetc(archivo);
    while(letra != EOF)
    {
        *(a + i) = letra;
        i++;
        a = realloc(a, sizeof(char)*(i + 1));
        letra = fgetc(archivo);
    }
    return a;
}

1 个答案:

答案 0 :(得分:0)

简而言之,您的代码所做的是一次从一个文件中读取1个字节,并不断将读取的内容写入内存中的新位置。

以下是步骤:

为char存储1字节(8位)内存以存储文件内容:

a = malloc(sizeof(char));

注意:由于整个文件的内存不足,程序会不断重新分配,循环中一次1个字节(下面有更多评论)。

打开文件流:

archivo = fopen("frases.txt", "r");

读取流体系结构中的第一个字母(frases.txt):

letra = fgetc(archivo);

开始循环读取直到文件结束(EOF):

while(letra != EOF)
{   
    *(a + i) = letra;

这会将从fgetc()读取的字母复制到您的指针a - 此 - &gt; *(a + i)是指针算术。它本质上意味着从内存地址i引用内存a字节中的位置。只有*a没有( + i)会将字母写入内存的开头(字符指针)。

您的主要问题:

为什么(i + 1)中有a = realloc(a, sizeof(char)*(i + 1));

realloc()创建所请求大小的新内存并将输入缓冲区复制到新空间,这可能是@hans批评代码的原因(以及您读取整个文件一个字符的事实)在一个时间)。稍微改进的是一次读取1024个字符,然后重新分配。要了解有关如何从文件中读取字符的更多信息,请研究堆栈溢出或谷歌。

不要忘记,i在此代码中继续增加1:i++

例如,如果您已将"hola mundo"从文件中读到缓冲区a,则i的值为10realloc()在内存中创建了一个全新的位置。因此,如果您分配了10个字节,那对于"hola mundo"和终止NULL字节就足够了:'\0',但对于下一个字符'!'和{'\0'来说还不够{1}}字节。因此,您需要为i分配内存(对于NULL字节,当前长度为+ 1)+ 1为下一个字符分配更多内存。