我有一个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实例。如果这确实是它的原因。或许我错过了一些东西。
我非常欣赏第二双眼睛,因为我没有想法。感谢。
答案 0 :(得分:4)
有多个错误会导致内存损坏。
其他答案已经提到内存分配不足。但那是你问题中最不重要的。
Operand
的构造函数无法初始化message
成员。然后,析构函数可能会尝试delete
一个从未创建过的指针。
显示的班级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'
会覆盖内存中的下一个字节,从而导致未定义的行为。