带有“new”的指针和带有“&variable”的指针有啥区别[重复]

Posted

技术标签:

【中文标题】带有“new”的指针和带有“&variable”的指针有啥区别[重复]【英文标题】:What's the difference between a pointer with "new" and pointer with "&variable" [duplicate]带有“new”的指针和带有“&variable”的指针有什么区别[重复] 【发布时间】:2017-09-21 19:52:11 【问题描述】:

我有一个简单的问题,但有时我有点困惑。

第一个代码:

Person *ptoPerson = new Person;
cout << ptoPerson->printMsg("Hi") << endl;
delete ptoPerson;

第二个代码:

Person p;
Person *ptoPerson = &p;
cout << ptoPerson->printMsg("Hi") << endl;
delete ptoPerson;

删除指针时出现问题。 第一个代码工作正常,指针被删除,但第二个代码在执行时出现问题。

为什么第二个代码不能删除指针? 我认为这两种情况下的指针都是指针,可以删除,还是我错了。

【问题讨论】:

相同的代码.. 你不能删除不是new分配的东西。 如果你使用&amp;variable,当你退出它的作用域时变量会消失,它不能被delete删除。 你应该熟悉storage duration的概念。 两个指针都是局部变量。不同之处在于他们指向的内容。第一个指针指向一个动态分配的对象,第二个指向一个自动存储的对象。 【参考方案1】:
Person *ptoPerson = new Person

这个指针指向一个heap内存区域(new Person),由程序员从堆中分配。 ptoPerson指向的对象失效后,必须将其删除,否则会导致内存泄漏

Person p;
Person *ptoPerson = &p;

这个指针指向一个由编译器维护的stack内存区域。当区域超出代码范围时,编译器会自动删除。如果你手动删除堆栈的内存区域,程序会崩溃,因为这是对程序的非法操作。

更多详情请点击本博客C++ MEMORY ALLOCATION

【讨论】:

@LionKing:And wrong,更不用说没有真正解释你的核心误解(即你认为所有指针都需要“删除”)。不要把简洁误认为有用。 我看不出链接到 C#/.NET 资源对 C++ 问题有何用处。该页面的大部分(如果不是全部)对于 C++ 来说都是错误的/误导性的。 @BoundaryImposition:这个问题的关键是堆和栈,指针指向不同的内存区域(栈或堆)有不同的结果。并且程序员不能删除栈内存(本题的第二个指针),由编译器维护。 @licp: “这个问题的关键是堆和栈” 不,不是。您不仅误解了 C++ 中的存储持续时间(而是专注于过时的特定于实现的细节;“内存的堆栈和堆与任何编程语言都无关”:完全没有关系!),而且您没有触及问题的症结(如前所述)。 @BoundaryImposition:感谢您解决链接问题。【参考方案2】:

当一个指针是=new时,这意味着指针正在为其内容分配动态内存,当一个点设置为&amp;variable时,这意味着指针指向该变量的引用。因此,您可以delete 动态分配内存而不是变量。

【讨论】:

小心你的术语; “参考”意味着别的东西。【参考方案3】:

This answer 解释了为什么在第二个示例中在运行时发生错误。

您遇到了未定义的行为。

【讨论】:

【参考方案4】:

我认为这两种情况下的指针都是指针,可以删除,还是我错了。

你错了。

您不会“删除指针”;您删除了使用 new 创建的事物(通过将指向该事物的指针传递给 delete 运算符)。

这里,您没有使用new 创建任何内容,因此delete 没有任何内容。

理想情况下,您的代码应如下所示:

Person p;
cout << p.printMsg("Hi") << endl;

【讨论】:

谢谢,但我还是一头雾水,你的意思是这个Person *ptoPerson = &amp;p;等于Person p存储在堆栈中,不需要删除吗? @LionKing:是的。您可以获得指向任何对象的指针,但这不会改变对象。它不会神奇地使对象需要手动删除,或者改变它的分配方式,或者在内存中移动它。它仍然具有自动存储持续时间(“堆栈中”),因此仍然不需要手动删除。你把指针指向它是无关紧要的! @LionKing:那么请随时提出后续问题,直到您理解为止。

以上是关于带有“new”的指针和带有“&variable”的指针有啥区别[重复]的主要内容,如果未能解决你的问题,请参考以下文章

带有引用和指针的指针的重载返回

从 Swift 调用带有数组指针和 int 指针的 C 函数

使用带有结构和指针的 temp

带有函数指针和引用的模板参数推导[重复]

在 C++ 中使用带有多级指针和偏移量的 WriteProcessMemory()?

c ++对象数组+带有引用和指针的参数