fread()调用后的Segfault

时间:2014-04-23 04:27:20

标签: c++ gcc file-io fread

我有以下代码:

char*
Sender::PrepareData(char* filename, unsigned long long int bytesToTransfer)
{
    FILE* dataFile = fopen(filename, "rb"); 
    if (dataFile==NULL) {fputs ("File error",stderr); exit (1);}

    cout << "File Open: " << filename << endl;

    char* theData;
    size_t bytesRead = fread(&theData, 1, bytesToTransfer, dataFile);
    if (bytesRead != bytesToTransfer) {fputs ("Reading error",stderr); exit (3);}

    cout << "Data Read -- Num Bytes: " << bytesRead << endl;
    cout << "Data to Send: " << *theData << endl;

    return theData;
}

当这个方法被击中时,我的输出是:

  

文件打开:t.bin

     

数据读取 - Num Bytes:10

     

分段错误(核心转储)

我的t.bin文件包含以下内容:

  

这是一个测试。

     

98172398172837129837

     

alsjdf89u32ijofiou2

     

TEST TEST ...

     

!! ##测试测试!! ###(DLKAJ)

当我运行gdb时,segfault输出为:

File Open: t.bin Data Read -- Num Bytes: 10

Program received signal SIGSEGV, Segmentation fault. 0x00000000004015e2 in Sender::PrepareData (this=0x603010, filename=0x7fffffffe363 "t.bin", bytesToTransfer=10)
    at sender.cpp:98  98        cout << "Data to Send: " << *theData << endl;

有人能告诉我我做错了吗?

1 个答案:

答案 0 :(得分:2)

你需要一个缓冲区,theData只是一个指针。

这样的东西
char theData[1000];
size_t bytesRead = fread(theData, 1, bytesToTransfer, dataFile);

可能会有效,具体取决于bytesToTransfer

的最大值

如果您确定要阅读字符串,则在写入theData之前可能还需要终止cout

theData[bytesRead] = '\0';

如果要返回缓冲区,则需要在堆上分配缓冲区。

之类的事情要容易得多
std::vector<char>
PrepareData(char* filename, unsigned long long int bytesToTransfer)
{
  std::ifstream file(filename, file.binary);

  if (!file) {
    std::cerr << "File error";
    exit(1);
  }

  std::cout << "File Open: " << filename << '\n';

  std::vector<char> data(bytesToTransfer + 1);
  file.read(data.data(), bytesToTransfer);
  data.back() = '\0';

  if (!file) {
    std::cerr << "Reading error";
    exit(3);
  }

  std::cout << "Data Read -- Num Bytes: " << bytesToTransfer << '\n';
  std::cout << "Data to Send: " << data.data() << '\n';
  return data;
}

如果你正在做的只是从文件中读取char,你应该考虑使用string s。