堆栈上的内存泄漏

Jea*_*uel 3 c++ memory-leaks

通过非常糟糕的设计,是否有可能在没有堆分配的情况下在C++中创建内存泄漏?

我想到的一个例子,请纠正我,如果它不符合我的想法:

#include <iostream>
#include <string>

void WhatIsYourName()
{
  std::string name;
  std::cout << "What is your name? ";
  getline (std::cin, name);
  std::cout << "Hello, " << name << "!\n";

  WhatIsYourName();
}

int main()
{
  WhatIsYourName();
}
Run Code Online (Sandbox Code Playgroud)

对我来说,它似乎WhatIsYourName()std::string name在每次调用时初始化一个新的,但该函数永远不会超出范围,因此内存永远不会被释放.是对的吗 ?或者编译器是否足够智能以确定将来不会使用该变量,因此如果函数超出范围,它会删除它?

什么样的其他糟糕的设计只使用堆栈分配会造成内存泄漏?

vso*_*tco 5

你有一个不停止的递归调用(没有退出条件),所以为每个函数调用创建一个新的堆栈页面,直到程序因堆栈溢出而崩溃.编译器无法优化它.

关于你的上一个问题,是否有可能在没有堆分配的情况下创建内存泄漏(并且没有这种无限递归),我相信不是,局部变量会自动释放,这就是为什么这种类型的存储持续时间称为自动存储持续时间.


Nat*_*ica 5

不,不可能使用具有自动存储持续时间的对象(有些人称之为堆栈)来创建内存泄漏。当您有一个具有自动存储期的变量时,它会被程序自动清除。一旦范围结束,它在其中声明的内容就会被销毁,并且它拥有的所有资源都将被释放(只要它设计得当)。在您的示例中,即使您由于无限递归而从未退出范围,它也不是内存泄漏。如果无限递归被删除,而是在某个条件下结束,那么您声明的所有变量都将被清除。

要获得内存泄漏,您需要创建一个具有动态存储持续时间的对象(有些人称之为堆)并且永远不要清理它。当您有一个具有动态存储持续时间的对象时,编译器不会为您清理它。你需要确保你自己清理它。正是这种忘记或遗漏清理代码导致了内存泄漏。