新char期间访问违规/堆损坏

时间:2017-03-21 23:09:28

标签: c++

我有一个C ++代码示例,我无法解释为什么它随机导致应用程序因访问冲突或堆损坏而失败。我知道该示例包含当前不满意的代码(直接使用指向char的指针),但这仅用于学习目的。如果有人可以查看代码并让我知道如果你看到我错过的东西,我会非常感激。感谢。

class Operand
{
private:
    double value;
    char* message;
public:
    Operand(double value);
    ~Operand();
    char* operator+(const Operand& other);
};

Operand::Operand(double value)
{
    this->value = value;
}

char* Operand::operator+(const Operand& other)
{
    char s[256];
    double sum = this->value + other.value;
    sprintf_s(s, "The sum of %f and %f is %f", this->value, other.value, sum);
    this->message = new char[strlen(s)];  //this is where it sometimes crashes with an access violation
    strcpy_s(this->message, sizeof(s), s);
    return this->message;
}

Operand::~Operand()
{
    if (this->message != nullptr)
        delete[] this->message;
}

int main()
{
    double operand1, operand2;
    cout << "Please input the calculator parameters: operand1 operand2: ";
    cin >> operand1 >> operand2;

    auto Operand1 = Operand(operand1);
    auto Operand2 = Operand(operand2);
    char* message1 = Operand1 + Operand2;
    char* message2 = Operand2 + Operand1;
    cout << message1 << "\n";
    cout << message2 << "\n";

    return 0; //and sometimes it crashes right after outputting to cout
}

我不明白为什么两个char *消息指针会相互干扰,因为它们属于不同的Operand实例。如果这确实是它的原因。或许我错过了一些东西。

我非常欣赏第二双眼睛,因为我没有想法。感谢。

3 个答案:

答案 0 :(得分:4)

有多个错误会导致内存损坏。

其他答案已经提到内存分配不足。但那是你问题中最不重要的。

未初始化的指针

Operand的构造函数无法初始化message成员。然后,析构函数可能会尝试delete一个从未创建过的指针。

3/5违规规则

显示的班级violates the Rule Of The Three。至少,它还需要一个适当的复制构造函数和赋值运算符。

operator+泄漏内存

这会导致内存泄漏,因为delete的{​​{1}}现有内容未能message,如果已经分配了。

在粗略审查代码之后,这些都是显而易见的错误。可能还有更多。

答案 1 :(得分:3)

您需要为终止空值分配额外的字节:

this->message = new char[strlen(s) + 1]; 

答案 2 :(得分:1)

operator+中,您要为new char[strlen(s)]的新字符串创建地点。这是一个字符短;你需要为最后的'\0'留出空间。

当您将字符串复制到其中时,'\0'会覆盖内存中的下一个字节,从而导致未定义的行为。