C++指针作用域
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4570210/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
c++ pointer scope
提问by Kevin
What happens when you have the following code:
当您有以下代码时会发生什么:
void makeItHappen()
{
char* text = "Hello, world";
}
Does text
go out of scope and get deleted automatically or does it stay in the memory?
是否text
超出范围并自动删除或保留在内存中?
And what about the following example:
下面的例子呢?
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?
Does the same thing occur here?
同样的事情在这里发生吗?
Thanks!
谢谢!
回答by Kos
char* text = "Hello, world";
Here an automatic variable (a pointer) is created on the stack and set to point to a value in constant memory, which means:
这里在堆栈上创建了一个自动变量(一个指针)并设置为指向常量内存中的一个值,这意味着:
- the string literal in
""
exists through the whole program execution. - you are not responsible for "allocating" or "freeing" it
- you may not change it. If you want to change it, then you have to allocate some "non-constant memory" and copy it there.
- 字符串文字 in
""
存在于整个程序执行过程中。 - 您不负责“分配”或“释放”它
- 你可能不会改变它。如果要更改它,则必须分配一些“非常量内存”并将其复制到那里。
When the pointer goes out of scope, the memory pointer itself (4 bytes) is freed, and the string is still in the same place - constant memory.
当指针超出范围时,内存指针本身(4 个字节)被释放,字符串仍然在同一个地方——常量内存。
For the latter:
对于后者:
SomeClass* someClass = new SomeClass();
Then someClass
pointer will also be freed when it goes out of scope (since the pointer itself is on the stack too, just in the first example)... but not the object!
然后someClass
指针在超出范围时也将被释放(因为指针本身也在堆栈上,只是在第一个示例中)......但不是对象!
The keyword new
basically means that you allocate some memory for the object on free store- and you're responsible for calling delete
sometime in order to release that memory.
该关键字new
基本上意味着您为free store上的对象分配了一些内存- 您负责调用delete
某个时间以释放该内存。
回答by Prasoon Saurav
Does
text
go out of scope
是否
text
超出范围
Yes! It is local to the function makeItHappen()
and when the function returns it goes out of scope. However the pointed to string literal "Hello, world";
has static storage duration and is stored in read only section of the memory.
是的!它是函数的局部变量makeItHappen()
,当函数返回时,它超出了作用域。然而,指向的字符串文字"Hello, world";
具有静态存储持续时间,并存储在内存的只读部分。
And what about the following example:
......
Does the same thing occur here?
下面的例子呢?
……
这里也发生同样的事情吗?
Your second code sample leaks memory.
您的第二个代码示例会泄漏内存。
SomeClass* someClass = new SomeClass();
SomeClass* someClass = new SomeClass();
someClass
is local to main()
so when main returns it being an automatic variable gets destroyed. However the pointed to object remains in memory and there's no way to free it after the function returns. You need to explicitly write delete someClass
to properly deallocate the memory.
someClass
是本地的,main()
所以当 main 返回时,它是一个自动变量被破坏。然而,指向的对象仍保留在内存中,并且在函数返回后无法将其释放。您需要显式写入delete someClass
以正确释放内存。
回答by villintehaspam
The variable text does go out of scope (however the string literal is not deleted).
变量 text 确实超出了范围(但是字符串文字不会被删除)。
For objects that you allocate with new (like your SomeClass), you need to explicitly delete them. If you want objects allocated like this to be automatically deleted, take a look at boost smart pointers(std::unique_ptr if your compiler is c++0x aware).
对于使用 new 分配的对象(如 SomeClass),您需要显式删除它们。如果您希望像这样分配的对象被自动删除,请查看boost 智能指针(如果您的编译器支持 c++0x,则为 std::unique_ptr)。
This will automatically delete the allocated object when the shared pointer goes out of scope.
当共享指针超出范围时,这将自动删除分配的对象。
Your code would then look like this:
您的代码将如下所示:
int main(int argv, char **argv)
{
boost::scoped_ptr<SomeClass> ptr(new SomeClass);
// the object is automatically deleted
return 0;
}
Note: In this particular example, you could also use std::auto_ptr (but this will be deprecated in c++0x).
注意:在这个特定的例子中,你也可以使用 std::auto_ptr (但这将在 c++0x 中被弃用)。
Note 2: As was pointed out in the comments by Kos, it is in this case more appropriate to use boost::scoped_ptr or std::unique_ptr (c++0x). My answer first used boost::shared_ptr, which is more appropriate if you need to share ownership of a pointer between several classes for instance.
注 2:正如 Kos 在评论中指出的那样,在这种情况下使用 boost::scoped_ptr 或 std::unique_ptr (c++0x) 更合适。我的回答首先使用了 boost::shared_ptr,例如,如果您需要在多个类之间共享指针的所有权,则更合适。
回答by Cratylus
In the first example the string literal is stored in data segment of your executable.
In the second case you do not have to call delete
(in your example program just terminates) since on program termination the heap is freed anyway for the process.
Note though that there are OS (as I have read) that you have to explicitly release heap even if the program terminates since it will not be cleaned up at termination for you.
Of course programmer is responsible for memory management in C++ and objects you create on heap should be delete
ed once unneeded.
在第一个示例中,字符串文字存储在可执行文件的数据段中。
在第二种情况下,您不必调用delete
(在您的示例程序中只是终止),因为在程序终止时,无论如何都会为进程释放堆。
请注意,尽管有操作系统(如我所见),即使程序终止,您也必须明确释放堆,因为它不会在终止时为您清除。
当然,程序员负责 C++ 中的内存管理,您在堆上创建的对象应该在delete
不需要时进行编辑。