c ++指针范围

时间:2010-12-31 12:53:49

标签: c++ pointers scope

当您拥有以下代码时会发生什么:

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?

这里是否会发生同样的事情?

谢谢!

4 个答案:

答案 0 :(得分:24)

 char* text = "Hello, world";

这里自动变量(指针)在堆栈上创建并设置为指向常量内存中的值,这意味着:

  • ""中的字符串文字存在于整个程序执行中。
  • 您不负责“分配”或“释放”它
  • 你可能不会改变它。如果你想改变它,那么你必须分配一些“非常量内存”并将其复制到那里。

当指针超出范围时,内存指针本身(4个字节)被释放,字符串仍然在同一个位置 - 常量内存。

对于后者:

SomeClass* someClass = new SomeClass();

然后someClass指针在超出范围时也会被释放(因为指针本身也在堆栈上,只是在第一个例子中)... 但不是对象!

关键字new基本上意味着您为免费商店上的对象分配了一些内存 - 并且您有责任在某个时间调用delete以释放该内存

答案 1 :(得分:11)

  

text是否超出范围

是的!它是函数makeItHappen()的本地函数,当函数返回时,它超出了作用域。但是,指向字符串文字"Hello, world";具有静态存储持续时间,并存储在内存的只读部分中。

  

以下示例如何:

     

......
  在这里发生同样的事情吗?

您的第二个代码示例泄漏了内存。

SomeClass* someClass = new SomeClass();

someClassmain()的本地,因此当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