C++ 在正常块之后检测到堆损坏
我有下面的代码,不知道为什么在堆损坏检测到错误时,它击中Myclass的析构函数。我相信我正在正确地释放内存C++ 在正常块之后检测到堆损坏,c++,memory,memory-leaks,C++,Memory,Memory Leaks,我有下面的代码,不知道为什么在堆损坏检测到错误时,它击中Myclass的析构函数。我相信我正在正确地释放内存 #include <iostream> #include <vector> using namespace std; class MyClass{ private: char* mp_str; public: MyClass():mp_str(NULL){} ~MyClass(){ delete [] mp_str;
#include <iostream>
#include <vector>
using namespace std;
class MyClass{
private:
char* mp_str;
public:
MyClass():mp_str(NULL){}
~MyClass(){
delete [] mp_str;
}
void setString(const char* str);
void printString();
};
int main(){
MyClass* a = new MyClass();
std::vector<MyClass> myVector;
myVector.push_back(*a);
a->setString("Hello World");
myVector[0].setString("Goodbye world");
a->printString();
myVector[0].printString();
return 1;
}
void MyClass::setString(const char* const str){
if(!str)
return;
size_t len = strlen(str);
if(!this->mp_str){
this->mp_str = new char[len];
memset(mp_str, 0, len+1);
}
strncpy(mp_str, str, len);
}
void MyClass::printString(){
if(this->mp_str)
cout << mp_str;
else
cout << "No string found";
}
在main()中,我还添加了
delete a;
在调用return1之前 您需要分配字符串的长度+1,以说明空值。你把它设置好了
if(!this->mp_str){
this->mp_str = new char[len+1];
memset(mp_str, 0, len+1);
}
(在拉斐尔的回答被接受后发布,这是应该的。)
缓冲区溢出无疑是这一特定崩溃的根本原因,但通过简化实现,同时调整是否遵守规则,可以避免崩溃。也就是说,既然实现了析构函数(用于处理mp_str
),那么还应该实现复制构造函数和赋值运算符
但是,坚持小跑的另一种方法是根本不需要实现这些事情。在这种情况下,使用std::string
而不是char*
可以解决崩溃和小跑兼容问题:
class MyClass{
private:
std::string mp_str;
public:
void setString(const char* str) { mp_str = str ? str : ""; }
void printString() {
if (mp_str.size()) std::cout << mp_str;
else std::cout << "(mp_str is empty)";
}
};
class-MyClass{
私人:
std::字符串mp_str;
公众:
void setString(const char*str){mp_str=str?str:;}
void printString(){
如果(mp_str.size())std::我不需要。@yurikilochek:同意。修复了这个问题。@user315052:是的,我知道a
的一个副本被推到向量上,我需要一个深度副本。我应该遵循三的规则。但是,代码不应该抛出这样的错误。Rafael的回答帮助我指出了错误!@brainydexter:如果我确定它是根c因为你的崩溃,我会发布一个答案。作为评论,这表明你应该遵循一个建议(因为如果不修复,以后会导致类似的头痛)。Regards@user315052我感谢你发布链接(因此+1:)指引我正确的方向。我意识到这里发生了肤浅的复制,这应该得到纠正。在我继续做这件事之前,我在脑子里想,为什么这该死的东西在我身上哭泣和撞击。:)len+1把我带到了那里!不过,谢谢!我同意@Rafael!唉,我没看到这个:(@brainydexter请注意,这并不是唯一的错误。请参阅上面的评论(应该是答案)Yes and I(re)阅读你发布的TROT链接。我已经有一段时间没有练习过指针的乐趣了,所以我想我应该再次尝试一下这些东西。使用像string这样的类确实让你的生活变得简单。尽管有时你必须编写原始C!@BrianReinhold:智能指针比原始指针更可取,并且仍然会让代码保持兼容。
class MyClass{
private:
std::string mp_str;
public:
void setString(const char* str) { mp_str = str ? str : ""; }
void printString() {
if (mp_str.size()) std::cout << mp_str;
else std::cout << "(mp_str is empty)";
}
};