首页 > 解决方案 > 分段错误(核心转储)与字符串但不是与 char*

问题描述

我有一个非常奇怪和复杂的错误,与 C++ 中字符串的功能有关。我编写了使用在线 IDE 编译的 MWE(最小工作示例)(此处为代码):

#include <iostream>
using namespace std;

class BaseOption {
public:
    BaseOption& operator=(const BaseOption& option) {
        return *this;
    }
};

class DerivedOption: public BaseOption
{

public:
    string str = "foo";

    DerivedOption& operator=(const DerivedOption& option) {
        this->str = option.str;
        this->BaseOption::operator=(option);
        return *this;
    };
};

class BaseObject {
public:
    BaseObject(BaseOption* option) {
        this->option = option;
}
private:
    BaseOption* option;
};

class DerivedObject : public BaseObject {
public:
    DerivedObject(DerivedOption option)
    : BaseObject(this->OptionConstructor(option)){}
    DerivedOption option;
private:
    DerivedOption* OptionConstructor(DerivedOption& option){
        this->option = option;
        return &this->option;
    }
};


int main() {
    DerivedOption option;
    DerivedObject object(option);
    cout << "The program ran without error." << endl;
    return 0;
}

此代码在运行时返回分段错误 (SIGSEGV)

但是当我更换

string str = "foo";

经过

char* str = (char*)"foo";

代码正常工作。有人可以解释一下吗?

标签: c++stringsegmentation-fault

解决方案


你有非常奇特的DerivedObject. 把它改成这样:

class DerivedObject : public BaseObject {
public:
    DerivedObject(DerivedOption option)
        : BaseObject(&this->option)
        , option(std::move(option))
    {}

    DerivedOption option;
};

它仍然很奇怪,因为您将指向尚未构造option的成员的指针传递给构造函数BaseObject

BaseOption此外,您还应该在/中删除复制赋值运算符的DerivedOption实现或实现复制构造函数。


在您的示例函数OptionConstructor中,甚至在构造函数之前BaseObject调用,而且该函数调用尚未构造的成员的复制赋值运算符option,我认为这是未定义的行为(在您的情况下,它会导致程序崩溃)。


推荐阅读