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

use*_*028 0 c++ memory-leaks memory-management

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

   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();
}
Run Code Online (Sandbox Code Playgroud)

假设命令选项刚刚在程序运行时首次出现.用户选择"1",表示由commandoptions()子例程执行buy()子例程.

在执行buy()之后,它再次调用commandoptions().

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

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

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

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

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

Ton*_*ion 7

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

char* memory = new char[100]; //allocate 100 bytes
Run Code Online (Sandbox Code Playgroud)

然后你忘了,把这个记忆用在delete了记忆中

delete[] memory; //return used memory back to system.
Run Code Online (Sandbox Code Playgroud)

如果您忘记了,delete那么当您的程序运行时,您将把这个内存保留为正在使用中,并且不能再用于其他内容.看到内存是一种有限的资源,例如,在没有程序终止的情况下执行此操作数百万次,将使您无需使用内存.

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

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

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

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

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

//do stuff with r

} // end of scope destroys r and calls destructor, deleting memory
Run Code Online (Sandbox Code Playgroud)

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

您的代码确实具有无限递归,没有将终止递归的基本情况.

  • 实际上,你_never_使用`new []`; 你使用`std :: vector`.在这种情况下,没有内存泄漏. (6认同)
  • @ChrisCM:那是一只红鲱鱼.那里的讨论*是关于`char on_stack [N];`vs`std :: vector <char>`.讨论*这里*是关于`char*on_heap = new char [N];`vs`std :: vector <char>`. (6认同)
  • 是.继续.告诉我们有关开销的信息. (3认同)

San*_*ker 5

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

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

并回答您的具体问题:

  • 不,commandoptions永远不会回来.
  • 如果你使用非常广泛的内存泄漏定义,那么这是一个内存泄漏,因为你创建堆栈帧而不再删除它们.大多数人不会将其标记为(包括我).
  • 是的,你确实会最终导致堆栈溢出.
  • inline关键字不会在这一个差异.


ine*_*ght 5

内联关键字不会导致内存泄漏.

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

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

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