【问题标题】:How to properly read from .txt file and assign to structs with pointer, C++如何正确读取 .txt 文件并分配给带有指针的结构,C++
【发布时间】:2021-02-19 08:15:58
【问题描述】:

我正在尝试读取文件并对其进行反序列化。我一次输入两个字符串并将其分配给某个变量foobar。首先将foo 分配给NODE2 和ofc 位向量,然后将bar 分配给NODE2,但是当这种情况发生时foo 也分配给NODE2。我怀疑它与指针有关,但我想让struct NodeReading 有一个指向字符串的指针,以释放我最终将构建的树的空间。我计划在二叉树中拥有数十万个NodeReadings。我只想将字符串存储为指针,因为字符串也会很大。只有叶子会存储一个实际的字符串(内部节点用于根据它们的位集进行导航)。

#include <iostream>
#include <fstream>
using namespace std;

struct Read {
    string dna;
    bitset<5> bf;
};

struct NodeReading {
    bitset<5> bloom_filter;
    string* dna_string;
};

static const string file = "tree.txt";
ifstream ist {file};

//could be a pair return instead of Read, but I like it this way.
Read read_line() {
    string a;
    bitset<5> b;
    ist >> a >> b;
    return Read {a, b};
}

NodeReading write_to_tree() {
    Read s = read_line();
    NodeReading hey {s.bf, &s.dna};
    return hey;
}

int main {
    NodeReading foo = write_to_tree(); //gets assigned NODE1 at first
    NodeReading bar = write_to_tree(); //gets assigned NODE2, and then foo also gets assigned NODE2

    return 0;
}

tree.txt:

NODE1 11110 NODE2 11110

【问题讨论】:

  • 指针&amp;s.dnas的生命周期结束时失效,也就是函数返回的时候。你为什么要存储一个指针? (std::string 是一个非常小的对象,字符串和指针比字符串占用更多的空间。)
  • 我计划在二叉树中拥有数十万个NodeReadings。我只想将它们存储为指针。字符串也会很大。
  • @GoldenRetriever 如果您正在创建一棵树,那么您将从堆中分配树的节点。因此复制字符串不是问题,因为它们将成为永远不会复制的节点的一部分(因为它们总是被指针引用)。在节点中按值存储字符串。
  • “我只想将它们存储为一个指针。”当你构建你的树时,你已经拥有了。您的树节点很可能是动态的,因此它们的内容也是如此。更多间接并不意味着更多更好。仅供参考,一旦您违反实施短字符串优化 (SSO),std::string 就已经是动态的,因此堆管理也已经为您完成了。
  • @GoldenRetriever 这是一个非常重要的软件设计原则。很难提前知道设计效率低下的地方在哪里。所以从一个干净简单的设计开始(在这种情况下,这意味着不要尝试使用字符串指针)。然后当你的代码工作时测试它,看看字符串是否有问题。如果是,那么是时候开始研究更复杂的设计了。到那时,您将处于一个更好的地方,能够就需要改进的地方做出正确的决定。

标签: c++ pointers serialization struct deserialization


【解决方案1】:

无论发生什么,实际上都是未定义的行为。如果您在这两行之间进行一些其他处理 - NodeReading foo = write_to_tree();NodeReading bar = write_to_tree(); 然后尝试访问 foo,那么您的应用程序很可能由于分段错误而崩溃。

write_to_tree() 内部,您的变量Read s 未在堆上分配,因此一旦您从该函数返回,变量Read s 就会超出范围,您会丢失其中的所有数据。您需要在堆上分配它。

在您的代码中,struct NodeReading 看起来是多余的。可以直接使用struct Readstruct NodeReading只是struct Read的位域的一个拷贝和一个指向其字符串的指针。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-22
    • 1970-01-01
    • 1970-01-01
    • 2018-10-19
    • 2021-11-20
    • 2012-09-16
    • 1970-01-01
    • 2015-01-12
    相关资源
    最近更新 更多