Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/153.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
堆栈上的内存泄漏 是否有可能通过不好的设计?< /P>在C++中没有“内存分配创建内存泄漏?_C++_Memory Leaks - Fatal编程技术网

堆栈上的内存泄漏 是否有可能通过不好的设计?< /P>在C++中没有“内存分配创建内存泄漏?

堆栈上的内存泄漏 是否有可能通过不好的设计?< /P>在C++中没有“内存分配创建内存泄漏?,c++,memory-leaks,C++,Memory Leaks,我想到的一个例子是,如果它没有达到我认为的效果,请纠正我: #include <iostream> #include <string> void WhatIsYourName() { std::string name; std::cout << "What is your name? "; getline (std::cin, name); std::cout << "Hello, " << name <<

我想到的一个例子是,如果它没有达到我认为的效果,请纠正我:

#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();
}
#包括
#包括
作废你的名字
{
std::字符串名;

std::cout您有一个不会停止的递归调用(没有退出条件),因此每次函数调用都会创建一个新的堆栈页,直到程序因堆栈溢出而崩溃。编译器无法对此进行优化


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

这个问题比您可能认为的更有趣。根据定义,没有内存泄漏,因为只有当a)指向已分配内存的指针丢失时才会发生内存泄漏(这里不是这种情况)或者b)在程序正常退出之前,指针永远不会被释放。第二种情况也不是这样,因为该程序永远不会正常退出


然而,字符串变量的实际情况有一个有趣的问题。由于递归调用发生在函数的末尾,从外观上看,代码可能是尾部调用优化的候选。但是,如果检查程序集,它不会发生,因为编译器需要调用字符串析构函数或者在尾部调用返回后。我个人认为这是优化中的一个缺陷,因为编译器应该能够看到调用后未使用字符串变量,并提前将其销毁。

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


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

< P>我想你误解了C和C++世界中内存泄漏的原因。 在“没有堆分配”的情况下,不可能泄漏内存

通常与动态内存分配关联,然后失去取消分配的能力。 例如:

// Memory leak
int x;
int *q = new int;
q = &x; // memory leak because the "allocated" q is lost.

使用和不使用<代码>新< /COD> +>代码>删除< /C>内存管理,在C++中很容易避免。

< P>如果编译器有bug,你可能会有堆栈内存泄漏。调用局部变量的析构函数。检查。< /p>这不是内存泄漏。这是无限递归。如果没有变量,它仍然会崩溃。它是如何以及为什么会崩溃的?当我编译它时它运行良好, GETLeI> <代码>暂停每个递归上的函数。这取决于你所说的内存泄漏。在C++世界中,这是一个内存泄漏。不是内存泄漏。请看答案。它将永远运行,并伴随着递归,这意味着堆栈溢出。明白了。那么,在没有堆分配的情况下是否可能创建内存泄漏?嗯,我也会这么想,但是GCC和Clang,即使你将
std::string
放在本地范围内。@TartanLlama,我知道。我很高兴注意,示例使用了执行堆分配的
std::string
。由于间接堆分配似乎在起作用,因此有
std::make_unique(1)。release();
@RaymondChen这是一个很好的观点,尽管我相信
std::string
在这种情况下将使用(将内容放置在堆栈上)。