【问题标题】:Is it a memory leak?是内存泄漏吗?
【发布时间】:2012-08-08 19:48:13
【问题描述】:

我是 C++ 新手,刚刚了解了动态内存和内存泄漏。

据我了解,在创建指针(int *ptr = new int),然后更改他指向的地址时,旧地址仍然存在/分配。 (如果我错了,请纠正我)。

所以我想到了这个:

int *ptr;
ptr = new int;

第一个 ptr 填充随机(或不?)地址,然后我更改它,所以旧的保留? 如果我尝试这段代码:

int *ptr;
cout << ptr << endl ;
ptr = new int;
cout << ptr << endl ;

我明白了:

0x401a4e
0x6d2d20

这是否意味着 0x401a4e 是内存泄漏的一部分?还是当 ptr 移动到动态内存时释放?它是如何工作的?

【问题讨论】:

  • 应该指出的是,一旦您学习了内存管理的基础知识(请参阅下面的 Konrad Rudolph 以获得简洁的描述),那么您应该停止使用它,而不是通过智能指针/容器进行自动内存管理.在实际代码中,您很少手动管理 RAW 指针。

标签: c++


【解决方案1】:

您需要了解内存泄漏与指针无关(真的:从不 - 尽管很多人会声称不同)。有指针的整个业务只是误导。

它们是关于动态内存分配和释放的不匹配。

通过new 的每个分配都必须与通过delete完全匹配 解除分配相匹配。 mallocfreenew[]delete[](以及其他可能的动态资源分配函数)也是如此。

int* x; // Not a memory leak: no dynamic allocation
new int; // Memory leak: we acquired a value via `new` and lost it.

int* y = new int;
int* z = y;
delete y; // Not a memory leak any more: we freed the memory.

delete z; // Oooh, bad: we deleted a value twice. The horror.

现代 C++ 代码很少使用(在大多数情况下:no)手动动态内存分配。这样,您就不会发生泄漏。原则上。这非常好,就这样做吧。除了手动动态内存分配,您可以使用标准容器和智能指针来为您处理内存管理。

【讨论】:

  • 我一直想知道为什么 delete 不会自动将指针设置为 NULL。至少它可以帮助人们编写意大利面条代码。
  • 我认为现代 c++ 代码仍然使用手动动态内存分配(有时甚至很多),但通过立即将分配的内存填充到某种智能指针中来避免泄漏的可能性。
  • @AlexBelanger:什么?智能指针与编译器没有任何关系。分配内存并将结果指针指向一个对象,该对象将在其销毁时自动释放(尽管如果不注意潜在的指令重新排序,可能会出现错误情况)
  • @Alex 我当时不明白这个笑话:将指针设置为0不会阻止在同一个目标上调用delete 两次 i> – 只在同一个 pointer.
  • @Grizzly C++03 和 C++11 的许多创新(在编译器和库中)的全部意义在于减少手动动态内存分配的需要。如果你发现自己使用了很多这些,你可能做错了什么。运行时多态类层次结构的普遍使用就是这样一个错误:它们被过度使用了。 C++ 提供了许多特性,使得这种层次结构在许多情况下变得多余。
【解决方案2】:

第一行 (int *ptr;) 没有分配任何动态内存,因此没有内存泄漏。您看到的值未初始化。它不是一个有效的指针。在给它赋值之前,你不应该删除指针。这样做将是未定义的行为。

【讨论】:

  • 虽然如果你现在做另一个ptr = new int,而不删除旧指针,那么你会泄漏内存。
【解决方案3】:

不,这不是内存泄漏。不同之处在于,当您说“new int”时,您是在告诉 C++ 保留一块内存来保存int;如果你丢失了指向那个保留块的指针,那么它就不能被恢复,也不能被释放,因此它是一个泄漏,因为它永远不能被重用。

仅在指针变量中保存一些位不会发挥任何作用;它们只是一点点。它使用new 分配内存可能会给您带来麻烦。一旦你保留了一个区块,你必须确保不会丢失它。

【讨论】:

  • @AlexBelanger -- 我做到了。你认为我错过了什么?
  • 我认为他在问为什么打印的两个输出不一样,并且担心他只是造成了内存泄漏。我看到的错误是第一个指针没有初始化,所以它指向一个随机内存地址......因此输出不同,但他的代码没有泄漏(还)。
  • 是的,这正是我的回答所说的,就像这个页面上的所有其他回答一样。
  • 嗯,在我看来,这是一个过于深入的答案。即使它是正确的,并且这些建议在玩指针时要牢记在心,你也不会向他解释为什么他首先会得到那个“奇怪”的结果。
【解决方案4】:

在 C/C++ 中,内存不会自动释放。所以,是的,如果你这样做:

 YourType* ptr = new YourType();
 ptr = new YourType();

你会有内存泄漏。

但在您的情况下,您没有内存泄漏,因为第一个值不是有效的内存位置。它是一个未初始化的指针。

【讨论】:

    猜你喜欢
    • 2011-02-20
    • 2013-08-12
    • 2019-04-02
    • 2013-01-08
    • 2013-11-12
    • 2015-05-04
    相关资源
    最近更新 更多