我尝试在C中逐行读取文件(但由于某些原因,我希望在最后将这些行连接成一个字符串!)。
int max_line_length, finish_length, current_length;
max_line_length = finish_length = 50000;
current_length = 0;
line = malloc(sizeof(char) * max_line_length);
finished_line = malloc(sizeof(char) * finish_length);
while (fgets(line, max_line_length, file) != NULL) {
if (line[strlen(line)-1] == '\n') {
int len = strlen(line);
char new_part[len];
strncpy(new_part, line, len - 1);
new_part[len - 1] = '\0';
if ((current_length + (len - 1)) > finish_length) {
while ((current_length + (len - 1)) > finish_length) finish_length*=2;
finish_line = realloc(sizeof(char)*finish_length);
}
current_length+= strlen(new_part);
strncat(finish_line, new_part, strlen(new_part));
line[0] = '\0';
} else {
max_line_length *= 2;
line = realloc(sizeof(char) * max_line_length);
}
}
所以我检查是否读取了换行符,如果没有,它应该意味着没有足够的内存,所以我重新分配它,然后它会被再次读取,对吧?
我不知道我在这里想念的是什么,但是valgrind抱怨说:
4,096 bytes in 1 blocks are definitely lost in loss record 111 of 114
at 0x47F1: malloc (vg_replace_malloc.c:302)
==901== by 0x180915: fgets (in /usr/lib/system/libsystem_c.dylib)
在我打电话给fgets的那一行!
但是我释放了两个方法,即方法结尾处的line和finished_line。有人看到我在这里错过了什么???
答案 0 :(得分:0)
参见realloc的定义:
void *realloc(void *ptr, size_t size);
在您的情况下,您在调用realloc时不提供任何ptr
参数。对我来说,这甚至都没有编译:
错误:函数'realloc'的参数太少
Realloc返回指向新分配内存的指针。您应该将旧指针传递给realloc并使其返回到新指针,如:
char* new_finished_line = NULL;
new_finished_line = realloc(finished_line, sizeof(char)*finish_length);
/* if realloc was successful, it already freed finished_line pointer
* and it returned to new_finished_line */
if (new_finished_line != NULL) {
finished_line = new_finished_line;
}
/* if new_finished_line is NULL, then finished line is still allocated */
else {
free(finished_line);
printf("realloc error\n");
exit(1);
}
但是,经过一些语法修复后,我的机器上的版本没有使内存泄漏。也许想想重新设计你的算法?您可以尝试使用下面的代码,其中file由char读取char,如果读取了换行符,则将空间写入缓冲区。实现这一目标的方法有很多种。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* read_my_file(char* name) {
char* store;
char* new_store = NULL;
int SIZE = 10;
int x;
int i = 0;
store = malloc(SIZE);
FILE* fp = fopen(name, "r");
while (( x = fgetc(fp) ) != EOF) {
if (x == '\n') {
store[i] = ' ';
}
else {
store[i] = x;
}
if (i > SIZE - 2) {
SIZE *= 2;
new_store = realloc(store, SIZE);
if (new_store != NULL) {
store = new_store;
}
else {
fprintf(stderr, "realloc error");
free(store);
exit(1);
}
}
i++;
}
store[i] = '\0';
fclose(fp);
return store;
}
int main(void)
{
char* container = read_my_file("YOUR_FILE_TO_READ.txt");
printf("%s\n",container);
free(container);
return 0;
}
我的算法可能不是最好的算法,我只想表明有很多方法可以做到这一点。