[英]Segmentation fault when reading from a file
我有以下功能:
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__);
之間的行上遇到分段錯誤printf("LINE=%u\\n", __LINE__);
陳述。 我不明白為什么會這樣。 當我查看此行時,似乎(*data)
將具有(char *)
類型,該類型肯定可以與索引運算符[]
。
我想念什么?
可能if (result != size - 1)
測試失敗,然后將*data
重置為NULL
(這是內存泄漏,BTW),然后嘗試寫入(*data)[size-1]
-oops !
一些指針:
ftell失敗時返回-1,因此如果是這種情況,它將為0 size = ftell(file) + 1;
在某些平台上,size_t是unsigned int,請牢記這一點。
*data = NULL;
這不是一個好主意,先釋放它free( *data );
在代碼中放置一些if語句以捕獲錯誤,不要假設一切都會正常工作,例如assert( size>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;
}
這是問題的可能原因:
if (result != size - 1)// error reding file
{
*data = NULL;
}
printf("LINE=%u\n", __LINE__);
(*data)[size-1] = '\0';
如果有錯誤讀取文件,會發生什么? 您將*data
設置為NULL,然后立即嘗試取消引用它-壞棗。
請注意,這也會導致內存泄漏。 您不會釋放*data
指向的內存。
重組代碼,以便僅在讀取操作成功(*data)[size-1] = '\\0'
情況下執行(*data)[size-1] = '\\0'
:
if (result != size - 1)
{
free(*data);
*data = NULL;
}
else
{
(*data)[size-1] = 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.