微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

交换指针后删除动态分配的内存

如何解决交换指针后删除动态分配的内存

我对 C++ 比较陌生,我想同时了解内存管理和指针。

假设我有下面的代码

int* p1;
int* p2;
int* p3 = new int[some size];

p1 = p3;

std::swap(p1,p2);

如何正确删除动态分配的内存?做 delete[] p3 就够了吗?之后我也应该删除 p2 吗?

解决方法

当你做这样的事情时,口语中有一些模糊:

delete x;

我们说“我们删除 x”。严格来说是错误的,因为删除的是x指向的对象。

通过 new/new[] 分配的每个对象都必须通过对 delete/delete[] 的一次调用销毁。无论您有两个或多个指向同一对象的指针都不会改变这一点。

int* p1 = nullptr;
int* p2 = nullptr;
int* p3 = new int[some size];      // p3 points to the array

p1 = p3;                           // p1 points to the same array

std::swap(p1,p2);                  // now p1 == nullptr,p2 points to the array

请注意,在您的示例中,指针未初始化。读取它们的值会导致未定义的行为。由于这不是问题的关键,我通过初始化它们来避免这一点。

通过 new [] 创建了一个数组,而您必须通过 delete [] 删除该数组。您不能将其删除两次。所以要么调用 delete[] p3; 要么调用 delete[] p2;,但不能同时调用。

PS: 评论已经提到了智能指针,我也建议您阅读它们。现在你不应该使用原始的拥有指针。拥有指针是您需要调用 delete 的指针,它“拥有”指向的对象。原始指针应该只用于“观察”,即您永远不必担心在原始指针上调用 delete(或 delete[])。当然你仍然需要注意所指向的对象是否还活着,但这不是动态分配特有的:

 int* p;
 { 
     int x = 42;
     p = &x;         // p points to x;
 }                   // x goes out of scope
 // here p is not a valid pointer anymore
,

要了解这里发生的事情,添加一些调试语句会有所帮助,即:

std::cout << p1 << " " << p2 << " " << p3 << "\n";

跟踪将产生如下输出:

0 0 0x15e7eb0
0x15e7eb0 0 0x15e7eb0
0 0x15e7eb0 0x15e7eb0

(注意我将 p1 和 p1 初始化为 nullptr

p3 最初指向一些内存。在赋值 p1 = p3 之后,p1 现在指向与 p3 相同的内存地址。当您交换指针时,现在是 p2 指向与 p3 相同的内存地址。

这里有几点需要注意:

  • 必须delete[] 与相应的 new[] 配对(不要将 deletenew[] 等调用)
  • 对已删除的对象调用 delete 是未定义的行为
  • 在空指针上调用 delete 是完全安全的

如您所见,处理原始指针和内存分配很容易导致陷阱。通常建议使用智能指针,或者如果您有一个非拥有指针,则使用 observer_ptr 之类的抽象来清楚地指示代码中指针的用途。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。