C 从文件中读取行的未定义行为
当我使用这个函数读取一个文件的内容,然后使用双指针将其拆分为单独的行时,我会有一些奇怪的行为。大约有1/3次,它会扰乱程序中的其他一些内存,导致另一个字符串打印不正确,并且很少会出现malloc“object的校验和不正确”错误。我把它缩小到这个函数,因为我只在调用它时才得到这个行为C 从文件中读取行的未定义行为,c,C,当我使用这个函数读取一个文件的内容,然后使用双指针将其拆分为单独的行时,我会有一些奇怪的行为。大约有1/3次,它会扰乱程序中的其他一些内存,导致另一个字符串打印不正确,并且很少会出现malloc“object的校验和不正确”错误。我把它缩小到这个函数,因为我只在调用它时才得到这个行为 File* openFile(char* fn) { FILE* fp = fopen(fn, "rb"); fseek(fp, 0, SEEK_END); long f
File* openFile(char* fn)
{
FILE* fp = fopen(fn, "rb");
fseek(fp, 0, SEEK_END);
long fsize = ftell(fp);
fseek(fp, 0, SEEK_SET);
char* contents = malloc(fsize + 1);
fread(contents, 1, fsize, fp);
fclose(fp);
contents[fsize] = 0;
File* f = malloc(sizeof(File));
f->len = 0;
f->rows = NULL;
int lastNull = 0;
for(int i = 0; i < fsize; i++)
{
if(contents[i] == '\n')
{
contents[i] = '\0';
f->rows = realloc(f->rows, f->len + 1);
f->rows[f->len++] = &contents[lastNull];
lastNull = i + 1;
}
}
return f;
}
我不确定该函数是否出错。realloc(f->rows,f->len+1)中的内存分配不足。 建议修复
// realloc(f->rows, f->len + 1)
f->rows = realloc(f->rows, sizeof *(f->rows) * (f->len + 1));
对于潜在的大文件
typedef struct {
// int len;
size_t len;
char** rows;
} File;
if(contents[i]='\n')
未捕获文件中不以'\n'
结尾的最后一行
“我不确定函数有什么地方出错。”
在for
循环中,行:
f->rows = realloc(f->rows, f->len + 1);
导致非致命的运行时错误:
非致命运行时错误:“so1.c”,第44行,第23列,线程id 9804:没有足够的空间将表达式强制转换为“指针到指针”
到字符'。”
……对我来说,这最终导致:
致命运行时错误:“so.c”,第44行,第23列,线程id 9804:动态内存已损坏
如果您声明的目的:
“读入文件内容,然后使用双指针将其拆分为单独的行。”
符合您的实际意图,您可以通过一组更简单的步骤来实现这一点。伪代码:
读取文件以获取行数和最长行数。关闭文件fopen
- 分配内存,例如:
char**content=malloc(行*sizeof(*content))代码>(使用前的测试结果。)
- 为每行分配内存:
for(i=0;i
你知道,指针占用超过1个字节,对吗?另外,检查fopen、malloc和realloc的返回值。所有这些都可能会失败。你为结构选择的typedef名称,f->rows=realloc(f->rows,f->len+1)
虽然合法,但令人困惑。在这种情况下,它太类似于文件
@Gerhardh facepalm,是的,忘记了这一点。文件
是正确的吗?它似乎已经解决了这个问题。您可能会考虑将(f->len+1)*sizeof(File*)
重命名为len
或类似名称。另外rowcount
是一个奇怪的名称,因为不涉及lastNull
,但它是当前行开始的索引。是的,我在最后一行有这个问题NULL
f->rows = realloc(f->rows, f->len + 1);