【发布时间】:2014-04-03 06:22:51
【问题描述】:
因为是1000+行,所以我不打算过去整个源码,但是我对我感兴趣的事情专门构建了一个类似的案例。注意这个源码:
#include <iostream>
using namespace std;
class Person
{
public:
Person();
Person(char*);
~Person();
Person& operator=(const Person&);
friend Person& example(const Person&);
void print() const;
private:
char* name;
};
Person::Person()
{
name = new char[12];
name = "Temp";
}
Person::~Person()
{
delete[] name;
}
Person::Person(char* _name)
{
name = new char[strlen(_name)+1];
strcpy_s(name,strlen(_name)+1,_name);
}
Person& example()
{
char* TestName = new char[11];
TestName = "ShouldStay";
Person B(TestName);
return B;
}
void Person::print() const
{
cout << name;
}
int main()
{
example();
return 0;
}
在这种情况下,example() 函数将返回:
- example returned {name=0x007cad88 "îþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþ... } Person &
显然,在返回命令上调用了析构函数并删除了堆中的内存(所以我无法对指针做任何进一步的事情 - 它指向已经释放的内存 - 没有数据)。
我的问题是 - 如何避免这种行为?避免此类问题的最优雅方法是什么?
提前谢谢你!
【问题讨论】:
-
按值返回。遵循五个甚至更好的规则,rule of zero。
-
TestName = "ShouldStay";也不对。 -
请注意,您需要为此类定义(自定义)复制构造函数,以使按值返回正常工作。 (或遵循零规则;)
-
对于任意类型的数组,字符串 "workaround" -> 向量 "workaround" :) (其中 "workaround" = 安全简单的解决方案)
-
像
"hello world"这样的字符串字面量属于array of 12constchar,可以转换为在早期版本的 C++ 中指向 char 的指针。这种转换在 C++ 中不再存在。由于向后兼容,它在 MSVC++ 中可能仍然存在一段时间,但不要依赖它。如果您尝试更改字符串文字的任何字符,地狱就会崩溃。至于内存泄漏:它就在那里。 MSVC 可能无法检测到它,但您分配了一些内存,然后忘记了它的地址(通过用一些字符串文字的地址覆盖它)。
标签: c++ destructor