细微的记忆泄漏,这是常见的做法吗?

时间:2013-05-07 15:47:37

标签: c++ memory-management memory-leaks

我想我可能会在这里创建内存泄漏:

   void commandoptions(){
      cout<< "You have the following options: \n 1). Buy Something.\n  2).Check you balance. \n3). See what you have bought.\n4.) Leave the store.\n\n Enter a number to make your choice:";
      int input;
      cin>>input;
      if (input==1) buy();
      //Continue the list of options.....
      else
      commandoptions(); //MEMORY LEAK IF YOU DELETE THE ELSE STATEMENTS!
   }

inline void buy(){
    //buy something
    commandoptions();
}

让我们说命令选项刚刚首次运行该程序。用户选择“1”,表示由commandoptions()子例程执行buy()子例程。

执行buy()后,再次调用commandoptions()。

第一个命令选项()是否返回?或者我只是做了内存泄漏?

如果我创建一个除了调用自身之外什么都不做的子例程,它将导致 stackoverflow ,因为该子例程的其他'循环'永远不会退出。我在这做/接近这样做吗?

请注意,我在购买时使用了inline关键字...这有什么不同吗?

我很高兴地问我的教授,他似乎没有。 :/

编辑:我不能相信我没有使用循环,但谢谢,我学到了一些关于我的术语的新内容!

5 个答案:

答案 0 :(得分:7)

内存泄漏是您使用new分配内存的地方,如下所示:

char* memory = new char[100]; //allocate 100 bytes

然后在将此内存用于delete内存

后忘记了
delete[] memory; //return used memory back to system.

如果您忘记delete,那么当您的程序正在运行时,您将把此内存保留为 in-use ,并且无法重复使用其他内容。看到内存是一种有限的资源,例如,在没有程序终止的情况下执行此操作数百万次,将使您无需使用内存。

这就是我们自己清理的原因。

在C ++中,你会使用像RAII这样的习惯用法来防止内存泄漏。

class RAII
{
public:
    RAII() { memory = new char[100]; }
    ~RAII() { delete[] memory }
    //other functions doing stuff
private:
   char* memory;
};

现在你可以使用这个RAII类了,

{ // some scope
RAII r; // allocate some memory

//do stuff with r

} // end of scope destroys r and calls destructor, deleting memory

您的代码未显示任何内存分配,因此没有可见的泄漏。

您的代码似乎确实有无限递归,没有基本情况会终止递归。

答案 1 :(得分:5)

这基本上是一个没有基本情况的递归。因此,递归永远不会结束(直到你用完堆栈空间为止)。

对于你想要做的事情,你最好使用循环,而不是递归。

并回答您的具体问题:

  • 不,commandoptions永远不会回来。
  • 如果你使用非常广泛的内存泄漏定义,那么这是一个内存泄漏,因为你创建堆栈帧而不再删除它们。大多数人不会这样做(包括我)。
  • 是的,你最终会导致堆栈溢出。
  • inline关键字不会对此产生影响。

答案 2 :(得分:5)

Inline关键字不会导致内存泄漏。

如果这是您拥有的所有代码,则不应存在内存泄漏。它确实看起来像你有无限的递归。如果用户键入“1”,则会在commandoptions()内再次调用buy()。假设他们在那个中键入“1”。重复ad infinum,然后你最终崩溃,因为堆栈太深了。

即使用户没有输入“1”,你仍然会在commandoptions()内的else处再次调用commandoptions(),这会产生完全相同的结果 - 由于无限递归而崩溃

但是,我没有看到内存泄漏的确切代码。

答案 3 :(得分:2)

这与memory leak无关,无论commandoptions的值是什么,都会对input函数进行无限调用,这会导致堆栈崩溃。您的commandoptions功能需要一些退出点。

答案 4 :(得分:1)

这里没有内存泄漏。发生了什么(至少它看起来就像你那个被删除的代码片段那样)是你进入一个无限循环。如果尾调用优化未启动或编译器不支持,那么可能会耗尽堆栈空间(虽然有点难以确定您的调用是否实际处于尾部位置)