2

下面的代码片段在 linux 上运行,它报告 Segmentation Fault (Core Dump)。我发现调用析构函数时会发生错误,但不知道为什么。有人可以帮忙解释一下吗?

    class TStringPair{
    public:
        TStringPair(){
            memset(this, 0, sizeof(TStringPair));
        }


        string a;
        string b;
    };

    int main (int argc, char* argv[])
    {
        TStringPair test;
        return 0;
    }
4

2 回答 2

4

memset从字面上看,这会毁了你的课。std::stringa (以及许多其他 C++ 类)的内存不应该用零填充,但你应该填充两者。

为了说明为什么这是一个坏主意,请考虑一个std::string指向实际字符的指针。糟糕,它现在不是指向空字符串,而是指向 0。将非 C 对象归零还有其他原因,但它们与此示例不太相关。

我想删除memset并在其位置放置任何内容都会给出您想要的确切结果。

于 2013-10-13T01:38:42.087 回答
2

就在您的 TStringPair 构造函数的主体运行之前,std::string 类的默认构造函数被(自动)为您的两个字符串成员对象中的每一个调用。

std::string 默认构造函数将这两个对象的内容设置为其正确状态。那正确的状态是什么?我们不知道(无论如何,如果不查看 STL 源代码就不会知道),但这没关系,因为我们不必知道——我们可以依靠 std::string 类的实现者来做正确的事情。

但是,在这些构造函数运行之后,您的 memset 会通过并用零字节覆盖(无论他们写入的任何信息)......现在这些字符串对象处于损坏状态,因此当它们的析构函数运行时发生崩溃也就不足为奇了遇到这种腐败。

于 2013-10-13T01:39:49.960 回答