我一直听说在堆栈上分配了一个匿名临时值,它在包含表达式的求值结束时被销毁。
所以,如果我们有以下内容:
//A function defined as
int foo(int* p)
{ ...
// writing this explicitly to avoid confusion with the question
delete p;
}
int main()
{
foo(new int); // anonymous pointer?
return 0;
}
现在当从main()调用foo时,指向heap元素的匿名指针被复制到p,这意味着有两个指向同一堆元素的指针。即使我们最终使用foo中的delete删除数据并将指针设置为nullptr,我们仍然留下指向垃圾的匿名指针。当它超出范围时,这样的匿名指针是否被清除?
这种情况类似于使用shared_ptr的构造函数形式,该形式还将来自调用者的原始匿名指针转换为某些数据,以构造一个共享指针,其中指针值被复制到构造函数中。当这些匿名指针超出范围时,它们是否设置为NULL?
答案 0 :(得分:2)
我想我在你的问题中闻到了一种误解。但是,我可能错了;如果这样无视。
你问这个:
即使我们最终在foo中使用delete来删除数据并进行设置 指向nullptr的指针,我们仍然留有匿名指针 指着垃圾。这样的匿名指针是否被清除 超出范围?
这种情况类似于使用shared_ptr的构造函数表单 它还将来自调用者的原始匿名指针转换为某些数据 构造一个共享指针,指针值被复制到 构造函数。这些匿名指针在外出时是否设置为NULL 范围?
从这些问题来看,似乎你可能会认为设置一个指向null(“清除”它)的指针是释放它所指向的任何东西的重要部分。在C ++中,情况并非如此。要释放对象p
,请执行delete p;
,故事结束。你可能之后也会说p = nullptr;
如果你想确保任何看到p
的人后来意识到它是无效的,但无论你是否这样做,它之前指出的对象是走了。
所以在这个假设的代码中:
int foo(int* p)
{
//some content
delete p;
}
int main()
{
foo(new int); // anonymous pointer?
}
没有记忆被泄露,一切都很好。传递给foo
的临时匿名指针是否在foo
返回后引用垃圾的问题是没有意义的,因为临时在该点实际上是不可见的,并且不会进一步参与程序所做的任何事情(原始的)指针没有析构函数。)
但是在这个假设代码中:
int foo(int* p)
{
//some content, but no delete p
}
int main()
{
foo(new int); // anonymous pointer?
}
什么都不会删除匿名new int
,所以你有内存泄漏。
答案 1 :(得分:0)
不,它们不会自动删除。分配有自动存储的对象和POD是。分配有new
的对象或POD不是。
我们仍然留下指向垃圾的匿名指针。当它超出范围时,这样的匿名指针是否被清除?
它是匿名的,因此没有针对值包含的内容定义的行为。指针是C ++和C概念,因此编译器使用的中间体不会被任何标准描述。但是如果你想知道编译器会发生什么,你可以反汇编目标代码。表示指针的值可能已经存储在堆栈中,并且会在int
返回时收到指针(指针本身,而不是指向的main
)。
答案 2 :(得分:0)
没有。指针不是共享指针,默认情况下不会在C ++中自动删除。
void fn()
{
YourClass LocalObject;
...
} // LocalObject goes out of scope here and is destroyed automatically
void fn2()
{
YourClass *PointedObject = new YourClass();
} // Object pointed to by the pointer is not destroyed.
实际上PointedObject
需要在某个时候删除。您可能会返回指针或其他内容,并在完成此操作后致电delete
。