我有以下功能:
void read_file(char* path, char** data)
{
FILE* file = NULL;
size_t size, result = 0;
*data = NULL;
file = fopen(path, "rb");
if (file == NULL)// error opening file
{
return;
}
fseek(file, 0, SEEK_END);
size = ftell(file) + 1;
rewind(file);
*data = (char*)malloc(size);
if(*data == NULL)
return;
result = fread(*data, 1, size, file);
if (result != size - 1)// error reding file
{
*data = NULL;
}
printf("LINE=%u\n", __LINE__);
(*data)[size-1] = '\0';
printf("LINE=%u\n", __LINE__);
fclose(file);
return;
}
我在两个printf("LINE=%u\n", __LINE__);
语句之间的行上遇到了分段错误。我不明白为什么会这样。当我查看此行时,似乎(*data)
将具有(char *)
类型,它当然可以与索引运算符[]
一起使用。
我错过了什么?
答案 0 :(得分:5)
可能if (result != size - 1)
测试失败,然后您将*data
重置为NULL
(这是内存泄漏,BTW),然后您尝试写入(*data)[size-1]
- 哎呀!
答案 1 :(得分:1)
一些指示:
ftell在失败时返回-1,所以如果是这种情况则为0 size = ftell(file) + 1;
size_t是unsigned int,考虑到这一点可能会很好。
执行*data = NULL;
并不是一个好主意,首先将其释放free( *data );
在代码中添加一些if语句来捕获错误,不要认为一切都会正常工作
例如assert( size>0 );
答案 2 :(得分:0)
我已经测试了你的代码并且它适用于我 - 我已经添加了文件大小的返回以正确地将数据传递给fwrite。
> ./a.out arm-2010.09-good.tar.bz2 | sha1sum && sha1sum arm-2010.09-good.tar.bz2
alloc size of 37265592
6bdff517bcdd1d279fc84ab3a5fbbca34211a87c -
6bdff517bcdd1d279fc84ab3a5fbbca34211a87c arm-2010.09-good.tar.bz2
此外,Valgrind报告没有任何警告和错误,所以......好吧!
#include <stdio.h>
#include <stdlib.h>
size_t read_file(char* path, char** data)
{
FILE* file = NULL;
size_t size, result = 0;
*data = NULL;
file = fopen(path, "rb");
if (file == NULL)// error opening file
{
return 0;
}
fseek(file, 0, SEEK_END);
size = ftell(file) + 1;
rewind(file);
fprintf(stderr, "alloc size of %i\n", size);
*data = (char*)malloc(size);
if(*data == NULL)
return 0;
result = fread(*data, 1, size, file);
if (result != size - 1)// error reding file
*data = NULL;
(*data)[size-1] = '\0';
size--; // report file size
fclose(file);
return size;
}
int main(int argc, char** argv)
{
char* data;
if(argc<2)
return 0;
size_t siz = read_file(argv[1], &data);
if(data) {
fwrite(data, 1, siz, stdout);
free(data);
}
else {
fprintf(stderr, "No data returned\n");
}
return 0;
}
答案 3 :(得分:0)
以下是问题的可能来源:
if (result != size - 1)// error reding file
{
*data = NULL;
}
printf("LINE=%u\n", __LINE__);
(*data)[size-1] = '\0';
如果 读取文件时出错,会发生什么?您将*data
设置为NULL,然后立即尝试取消引用它 - 坏juju。
请注意,这也会导致内存泄漏;你没有释放*data
所指向的记忆。
重新构建代码,以便在读取操作成功时仅执行(*data)[size-1] = '\0'
:
if (result != size - 1)
{
free(*data);
*data = NULL;
}
else
{
(*data)[size-1] = 0;
}