2017-10-16 124 views
1

目前我在下面有下面的代码。 char **arr最初设置为NULL。然后在从文件读取时以文字形式存储。我只是随机选择了一个像5000这样的大数字,因为我不知道如何正确地做malloc业务,即使在网上查找并尝试学习之后。如何从文件读取(未知长度)时正确使用malloc和空闲char **?

而且,当我尝试freechar **arr(我的代码的最后一节),有时我得到segmentation faults,有时abort traps等。如果有人可以告诉我怎么做这样的事情正确,将不胜感激!谢谢!

char **arr = NULL 

File *fp = fopen("file.txt", "r") 
char string[3000]; 
char counter = 0; 


//to store 
while(fscanf(fp, "%s", string)!=EOF){ 
    arr = realloc(arr, 5000); //arbitrarily used a large number like 5000 
    arr[counter] = malloc(5000); 
    strcpy(arr[counter++], string); 
} 

//to free 

for(i=0; i<counter; i++){ 
    free(arr[i]) 
} 
free(arr); 
+1

可能重复[如何获取文件的大小在C?](https://stackoverflow.com/questions/238603/how-can-i-get-a-files-size-in-c) –

+0

使用[GCC](http://gcc.gnu.org/)编译所有警告和调试信息:'gcc -Wall -Wextra -g',然后**使用调试器**'gdb'和[valgrind]( http://valgrind.org/)。另请阅读[malloc](http://man7.org/linux/man-pages/man3/malloc.3.html)和相关文档 –

+0

请提供一些[MCVE]的解释。你的修复我的代码问题是脱节 –

回答

4

请勿使用任意数字。

传递给realloc的size参数是要分配的新字节数。在你的情况下,它可能是(counter + 1) * sizeof(char *)字节。如果该文件包含大约一千多字,则5000将不够。更何况你打电话realloc第一次电话后不改变大小。

而且不要使用malloc调用的任意值。请使用strlen(string) + 1,或者如果可用,则可以使用strdup代替。


最后,不要重新分配回你传递的指针realloc变量。如果realloc失败并返回NULL您将失去原始指针。

而是使用你O原来的指针变量分配backt之前检查一个临时变量:

char **temp = realloc(arr, ...); 
if (temp == NULL) 
{ 
    // ERRORO: Do something appropriate 
} 

arr = temp; 
+1

我会建议,而不是像'newsize = 4 * oldsize/3 + 10;'进展,并与'newsize'的'realloc'。当然,应该明确保留当前分配的大小。 –

+0

@Someprogrammerdude最后一个意思是什么?不要重新分配变量...等 – novice

+0

@novice更新了一个例子 –

1

检查函数getline的manual(),这个函数分配线适合你,如果*为NULL。使用这个函数可能是一个正确的方法,而不是使用strlen和fscanf。