C++ 损坏的堆
C++ Corrupted Heap
我的程序似乎在 main 方法 returns 时抛出一个关于损坏堆的运行时异常。我已采取适当的预防措施避免发生这种情况,包括复制构造函数。谁能解释一下为什么会这样?
MyString.cpp
#include "MyString.h"
#include <cstdio>
#include <Windows.h>
MyString::MyString() {
str = (char*)malloc(sizeof(char));
*str = '[=10=]';
}
MyString::MyString(char* src) {
int size = sizeof(char)*(strlen(src) + 1);
str = (char*)malloc(size);
strcpy_s(str, size, src);
}
MyString MyString::operator+(char* add) {
int addSize = sizeof(char)*strlen(add);
int fullSize = sizeof(char)*(strlen(str) + 1) + addSize;
str = (char*)realloc(str, fullSize);
char* temp = str;
temp += strlen(str);
strcpy_s(temp, addSize + 1, add);
return *this;
}
MyString::~MyString() {
if (str)
free(str);
}
MyString::MyString(const MyString &arg) {
int size = sizeof(char) * (strlen(arg.str) + 1);
str = (char*)malloc(size);
strcpy_s(str, size, arg.str);
}
main.cpp
#include <iostream>
#include "MyString.h"
using namespace std;
int main(int argc, char *argv[]) {
MyString test = MyString("hello!");
test = test + " world";
cout << test.toString() << endl;
cout << strlen(test.toString()) << endl;
system("pause");
return 0; //runtime error here
}
我正在根据@user4581301 的建议修复我的 post:
您应该修改加法运算符重载,以便它生成一个新对象并实现赋值运算符重载,如下所示:
MyString operator+(char* add) const {
int thisSize = sizeof(char)*strlen(str);
int addSize = sizeof(char)*(strlen(add) + 1);
int fullSize = thisSize + addSize;
char* tempStr = (char*)malloc(fullSize);
strcpy_s(tempStr, fullSize, str);
strcpy_s(tempStr + thisSize, fullSize, add);
return MyString(tempStr);
}
MyString& operator=(const MyString& assign){
int assignSize = sizeof(char)*(strlen(assign.str) + 1);
str = (char*)realloc(str, assignSize);
strcpy_s(str, assignSize, assign.str);
return *this;
}
你必须了解 Rule Of Three
使用了隐式赋值运算符,当旧对象被销毁时,新对象使用已经释放的指针,稍后它会尝试再次释放它。
我的程序似乎在 main 方法 returns 时抛出一个关于损坏堆的运行时异常。我已采取适当的预防措施避免发生这种情况,包括复制构造函数。谁能解释一下为什么会这样?
MyString.cpp
#include "MyString.h"
#include <cstdio>
#include <Windows.h>
MyString::MyString() {
str = (char*)malloc(sizeof(char));
*str = '[=10=]';
}
MyString::MyString(char* src) {
int size = sizeof(char)*(strlen(src) + 1);
str = (char*)malloc(size);
strcpy_s(str, size, src);
}
MyString MyString::operator+(char* add) {
int addSize = sizeof(char)*strlen(add);
int fullSize = sizeof(char)*(strlen(str) + 1) + addSize;
str = (char*)realloc(str, fullSize);
char* temp = str;
temp += strlen(str);
strcpy_s(temp, addSize + 1, add);
return *this;
}
MyString::~MyString() {
if (str)
free(str);
}
MyString::MyString(const MyString &arg) {
int size = sizeof(char) * (strlen(arg.str) + 1);
str = (char*)malloc(size);
strcpy_s(str, size, arg.str);
}
main.cpp
#include <iostream>
#include "MyString.h"
using namespace std;
int main(int argc, char *argv[]) {
MyString test = MyString("hello!");
test = test + " world";
cout << test.toString() << endl;
cout << strlen(test.toString()) << endl;
system("pause");
return 0; //runtime error here
}
我正在根据@user4581301 的建议修复我的 post:
您应该修改加法运算符重载,以便它生成一个新对象并实现赋值运算符重载,如下所示:
MyString operator+(char* add) const {
int thisSize = sizeof(char)*strlen(str);
int addSize = sizeof(char)*(strlen(add) + 1);
int fullSize = thisSize + addSize;
char* tempStr = (char*)malloc(fullSize);
strcpy_s(tempStr, fullSize, str);
strcpy_s(tempStr + thisSize, fullSize, add);
return MyString(tempStr);
}
MyString& operator=(const MyString& assign){
int assignSize = sizeof(char)*(strlen(assign.str) + 1);
str = (char*)realloc(str, assignSize);
strcpy_s(str, assignSize, assign.str);
return *this;
}
你必须了解 Rule Of Three
使用了隐式赋值运算符,当旧对象被销毁时,新对象使用已经释放的指针,稍后它会尝试再次释放它。