当您拥有以下代码时会发生什么:
void makeItHappen()
{
char* text = "Hello, world";
}
text
是否超出范围并自动删除或保留在内存中?
以下示例如何:
class SomeClass
{
public:
SomeClass();
~SomeClass();
};
SomeClass::SomeClass() { }
SomeClass::~SomeClass()
{
std::cout << "Destroyed?" << std::endl;
}
int main()
{
SomeClass* someClass = new SomeClass();
return 0;
} // What happend to someClass?
这里是否会发生同样的事情?
谢谢!
答案 0 :(得分:24)
char* text = "Hello, world";
这里自动变量(指针)在堆栈上创建并设置为指向常量内存中的值,这意味着:
""
中的字符串文字存在于整个程序执行中。当指针超出范围时,内存指针本身(4个字节)被释放,字符串仍然在同一个位置 - 常量内存。
对于后者:
SomeClass* someClass = new SomeClass();
然后someClass
指针在超出范围时也会被释放(因为指针本身也在堆栈上,只是在第一个例子中)... 但不是对象!强>
关键字new
基本上意味着您为免费商店上的对象分配了一些内存 - 并且您有责任在某个时间调用delete
以释放该内存
答案 1 :(得分:11)
text
是否超出范围
是的!它是函数makeItHappen()
的本地函数,当函数返回时,它超出了作用域。但是,指向字符串文字"Hello, world";
具有静态存储持续时间,并存储在内存的只读部分中。
以下示例如何:
......
在这里发生同样的事情吗?
您的第二个代码示例泄漏了内存。
SomeClass* someClass = new SomeClass();
someClass
是main()
的本地,因此当main返回时,自动变量会被销毁。但是,指向的对象仍然存在于内存中,并且在函数返回后无法释放它。您需要显式写delete someClass
以正确释放内存。
答案 2 :(得分:6)
变量文本超出范围(但不删除字符串文字)。
对于使用new分配的对象(如SomeClass),您需要明确删除它们。如果您希望自动删除这样分配的对象,请查看boost smart pointers(如果您的编译器支持c ++ 0x,则为std :: unique_ptr)。
当共享指针超出范围时,这将自动删除已分配的对象。
您的代码将如下所示:
int main(int argv, char **argv)
{
boost::scoped_ptr<SomeClass> ptr(new SomeClass);
// the object is automatically deleted
return 0;
}
注意:在这个特定示例中,您还可以使用std :: auto_ptr(但这将在c ++ 0x中弃用)。
注2:正如Kos的评论中指出的那样,在这种情况下使用boost :: scoped_ptr或std :: unique_ptr(c ++ 0x)更合适。我的回答首先使用了boost :: shared_ptr,如果你需要在几个类之间共享指针的所有权,这更合适。
答案 3 :(得分:1)
在第一个示例中,字符串文字存储在可执行文件的数据段中
在第二种情况下,您不必调用delete
(在您的示例程序中只是终止),因为在程序终止时,无论如何都要为进程释放堆。
请注意,虽然有操作系统(我已阅读),但即使程序终止,您也必须显式释放堆,因为在终止时它不会被清除。
当然,程序员负责C ++中的内存管理,而你在堆上创建的对象一旦被删除就应该delete
。