2017-10-14 100 views
0

很抱歉,如果这个问题是基本的,但我真的不明白为什么,如果我不添加“+ 1”节目不打印所有的字母试图了解如何做的realloc和malloc函数工作

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; 
} 
+0

你需要知道的唯一真实的事情是这个代码是多么可怕,可怕,致命的错误。谷歌“realloc o(n)复杂性”找到正确的命中。 –

+0

这看起来像是一个关于c字符串的问题,而不是'malloc'或'realloc'。如果你把'char'数组作为一个字符串,它必须是'NUL'终止的。 'printf(“%s”);'将继续打印字符,直到找到一个'\ 0''字符。所以如果你有字符串“Hello”,你实际上需要6个字符来表示字符串(5个字母加上'NUL'终止符)。这就是为什么你在为字符串指定的内存分配上看到+1的原因。 – yano

回答

0

总之,你的代码确实是一次一个文件1字节读取和写入连续什么读取到内存中新的地方。

这些步骤如下:

分配存储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 - 这 - >*(a + i)是指针算术。它实质上是指从内存地址a引用内存中的地址i字节。只要*a没有(+ i)会写信到你的记忆开始(字符指针)。

你的主要问题:

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

realloc()创建请求的大小和复印输入缓冲器的新的空间,这可能是为什么@hans critized代码(与您一次读取整个文件一个字符的事实一起)的新内存。稍微改进就是一次读取1024个字符,然后重新分配。要详细了解如何从文件中读取字符,请研究堆栈溢出或谷歌。

别忘了,i在此代码中一直递增1:i++

例如,如果您已经阅读您的文件"hola mundo"到您的缓冲区a,然后i将有10价值。 realloc()在内存中创建一个全新的地方。因此,如果您分配了10个字节,那么对于"hola mundo"和终止NULL字节:'\0'来说就足够了,但对于下一个字节'!''\0'字节不足。因此,您需要为下一个char分配i(NULL字节的当前长度+1)的内存+ 1