簡體   English   中英

從文件讀取時出現分段錯誤

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM