簡體   English   中英

嘗試使用重載運算符讀取二進制文件時出現分段錯誤>>

[英]segmentation fault when try reading binary file using overloaded operator >>

我正在嘗試讀取使用以下代碼創建的二進制文件:

#include <list>
#include <string>
#include <bitset>
#include <fstream>

struct Node {
  char data;
  int frequency;

  friend std::istream& operator>>(std::istream& input, Node& e) {
    input.read(&e.data, sizeof(e.data));
    input.read(reinterpret_cast<char*>(e.frequency), sizeof(e.frequency));
    return input;
  };

  friend std::ostream& operator<<(std::ostream& output, const Node& e) {
    output.write(&e.data, sizeof(e.data));
    output.write(reinterpret_cast<const char*>(&e.frequency), sizeof(e.frequency));
    return output;
  };
};

int main() {
  std::list<struct Node> list;

  for(char i='a'; i<='z'; i++) {
    struct Node n;
    n.data = i;
    n.frequency = 1;
    list.push_back(n);
  }

  std::string encoded_file = "";

  for(int i=0; i<100; i++) {
    encoded_file = encoded_file + "101010";
  }

  std::fstream output;
  output.open("output.txt", std::ios_base::out | std::ios_base::binary);

  if (output.is_open()) {
    output << list.size();
    for(int i=0; i<list.size(); i++) {
      output << list.front();
      list.pop_front();
    }

    for(long unsigned int i=0; i<encoded_file.length(); i+=8) {
      std::string data = encoded_file.substr(i, 8);
      std::bitset<8> b(data);
      unsigned long x = b.to_ulong();
      unsigned char c = static_cast<unsigned char>( x );
      output << c;
    }
  }

  output.close();

  return 0;
}

這段代碼似乎工作正常,並且文件output.txt生成沒有問題。

但是,當我嘗試使用此代碼讀取文件時:

#include <list>
#include <string>
#include <bitset>
#include <fstream>
#include <iostream>

struct Node {
  char data;
  int frequency;

  friend std::istream& operator>>(std::istream& input, Node& e) {
    input.read(&e.data, sizeof(e.data));
    input.read(reinterpret_cast<char*>(e.frequency), sizeof(e.frequency));
    return input;
  };

  friend std::ostream& operator<<(std::ostream& output, const Node& e) {
    output.write(&e.data, sizeof(e.data));
    output.write(reinterpret_cast<const char*>(&e.frequency), sizeof(e.frequency));
    return output;
  };
};

int main() {
  std::list<struct Node> list;
  std::string encoded_file = "";

  std::fstream input;
  input.open("output.txt", std::ios_base::in | std::ios_base::binary);

  if (input.is_open()) {
    std::cout << "1" << std::endl;
    int size = 0;
    input >> size;
    std::cout << "size: " << size << std::endl;

    for(int i=0; i<size; i++) {
      Node node;
      input >> node;
      std::cout << node.data << " (" << node.frequency << ")" << std::endl;
      list.push_back(node);
    }
    std::cout << "2" << std::endl;

    char c;
    while(input.get(c)) {
      std::bitset<8> b(c);
      encoded_file = encoded_file + b.to_string();
    }
    std::cout << "3" << std::endl;
  }

  input.close();

  return 0;
}

我得到一個分段錯誤。 當我嘗試執行input >> node; . 我檢查了一下,顯然當程序進入Node::operator>>時,讀取e.data ,但沒有讀取頻率。

誰能給我有關如何解決此問題的任何提示?

您的Node::operator>>中有錯字。 閱讀e.frequency時,您缺少一個&

input.read(reinterpret_cast<char*>(&e.frequency), sizeof(e.frequency));
                                   ^

這是我之前的答案中的一個錯字,您從那里獲得了此代碼。 我已經糾正了這個錯誤。


話雖如此,我在您的代碼中看到了其他問題。

您正在以二進制模式創建文件,但您沒有將所有內容作為二進制值流式傳輸到其中。 只有您的Node類作為二進制流式傳輸,而您的其他值則作為文本流式傳輸。 不要混合格式化方案。

output << list.size()output << c正在執行格式化的 I/O。 對於二進制 I/O,使用write()而不是operator<< ,例如:

size_t size = list.size();
output.write(reinterpret_cast<char*>(&size), sizeof(size));
...
unsigned char c = ...;
output.write(reinterpret_cast<char*>(&c), sizeof(c));

然后在讀取文件時反轉該過程,例如:

input.read(reinterpret_cast<char*>(&size), sizeof(size));
...
unsigned char c;
while(input.read(reinterpret_cast<char*>(&c), sizeof(c))) {
     ...
}

此外,在您創建文件的代碼中,您的第一個for循環是錯誤的。 您在循環遍歷列表時正在修改list ,從而影響其size() 所以你最終會跳過列表中的節點。 您應該使用迭代器而不是索引進行迭代,並且根本不修改列表,例如:

for(std::list<Node>::const_iterator iter = list.cbegin(); iter != list.cend(); ++iter) {
    output << *iter;
}

或更簡單:

for(const auto &item : list) {
    output << item;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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