Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 当堆上的数据超出范围时,堆上的数据指针是否被删除?_C++ - Fatal编程技术网

C++ 当堆上的数据超出范围时,堆上的数据指针是否被删除?

C++ 当堆上的数据超出范围时,堆上的数据指针是否被删除?,c++,C++,我一直听说在堆栈上分配了一个匿名临时变量,它在对包含表达式的求值结束时被销毁 因此,如果我们具备以下条件: //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; }

我一直听说在堆栈上分配了一个匿名临时变量,它在对包含表达式的求值结束时被销毁

因此,如果我们具备以下条件:

//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,这意味着有两个指向同一heap元素的指针。即使我们最终在foo中使用delete来删除数据并将指针设置为nullptr,我们仍然会留下指向垃圾的匿名指针。这样的匿名指针超出范围时是否被清除


这种情况类似于使用shared_ptr的构造函数表单,该表单还从调用者获取指向某些数据的原始匿名指针,以构造一个共享指针,其中指针值被复制到构造函数。当这些匿名指针超出范围时是否设置为NULL?

否,它们不会自动删除。分配了自动存储的对象和POD被删除。分配了
new
的对象或POD不可用

我们仍然有指向垃圾的匿名指针。这样的匿名指针超出范围时是否被清除


它是匿名的,因此没有定义值可能包含的行为。指针是C++和C概念,编译器所用的中介没有用任何标准来描述。但是如果你想知道编译器会发生什么,你可以反汇编目标代码。很可能表示指针的值可能已经被存储在堆栈上,并且在代码< >主< <代码> >时返回(指针本身,而不是<代码> INT/COD> >)。指针不是共享指针,在C++中默认不会自动删除。p>
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

我想我在您的问题中发现了一个误解。然而,我可能错了;如果是这样,则不予理会

你问:

即使我们最终在foo中使用delete来删除数据和设置 指向nullptr的指针,我们仍然剩下匿名指针 指向垃圾。这样的匿名指针被清除了吗 超出范围

这种情况类似于使用shared_ptr的构造函数形式 这也会将调用方指向某些数据的原始匿名指针 构造一个共享指针,将指针值复制到 构造器。这样的匿名指针在退出时是否设置为NULL 范围

从这些问题来看,您可能会有这样的印象:将指针设置为null(“清除”它)是释放它指向的任何内容的一个重要部分。在C++中,情况并非如此。要释放
p
指向的对象,请执行
删除p,故事结束。你也可以说
p=nullptrp
的任何人都意识到它是无效的,那么无论您是否这样做,它之前指向的对象都会消失

在这个假设代码中:

int foo(int* p)
{
   //some content
   delete p;
}

int main()
{
  foo(new int); // anonymous pointer?
}
int foo(int* p)
{
   //some content, but no delete p
}

int main()
{
  foo(new int); // anonymous pointer?
}
没有内存泄漏,一切正常。传递到
foo
的临时匿名指针是否在
foo
返回后引用垃圾的问题毫无意义,因为临时指针在该点上实际上是不可见的,并且不会进一步参与程序所做的任何事情(原始指针没有析构函数)

但在这个假设代码中:

int foo(int* p)
{
   //some content
   delete p;
}

int main()
{
  foo(new int); // anonymous pointer?
}
int foo(int* p)
{
   //some content, but no delete p
}

int main()
{
  foo(new int); // anonymous pointer?
}

不会删除匿名
新int
,因此内存泄漏。

与POD无关。所有自动存储对象都被“删除”。除此之外,它们不会被自动删除。
答案是无用的。重要的是要理解,尽管
delete
使用指针,但操作实际上是在它指向的内存上执行的。因此,如果有两个(或三个,或四个,或n个)指针都指向同一个动态分配的对象,只要对其中一个对象调用
delete
,就不会泄漏内存。当它超出范围时,它就消失了。无法命名。尝试(例如预先使用绑定到它的引用)是未定义的行为。所以问它的值是空指针还是空指针是没有意义的。指针值不存在。将new与delete配对,或将所有权委托给std::unique\u ptr/std::shared\u ptr(没有自动删除指针)在删除后将指针设置为
nullptr
,这在某些情况下是一种很好的做法,因为这会使指针明显不再有效,但正确的内存管理并不需要它。或者换句话说,在C++中,设置一个空指针对它指向的事物没有影响。这与C#和Java不同,在C#和Java中,做同样的事情可能会使对象成为垃圾收集的候选对象。人们对你的问题感到困惑,因为他们认为你的意思是删除不存在。在编写代码时,不会导致内存泄漏。谢谢。我理解你的评论。我所说的删除并不是指针指向的数据。我想问的是,当临时指针超出范围时,指针本身是否被删除。@avish指针位于堆栈上,因此不需要删除。一般来说,如果不使用
new
,一切都很好。指针只是一个数字;当一个函数超出范围时发生的情况与
int
函数发生的情况相同,这将泄漏一个
int*
,但这将是一件非常奇怪的事情。