C++ 使用goto会导致内存泄漏吗?

C++ 使用goto会导致内存泄漏吗?,c++,memory-leaks,goto,C++,Memory Leaks,Goto,我有一个程序,在这个程序中,我需要打破一大堆嵌套的for循环。到目前为止,大多数人告诉我的方法是在我的代码中使用丑陋的goto 现在,如果我在循环中创建一组本地堆栈(我想这就是它们的名称,如果不是,我的意思是只使用常规变量而不使用新命令)变量,我的程序会点击触发goto的if语句,由于我的程序不正确地退出了许多循环,并且没有清理本地变量,我是否会遇到内存泄漏?不,您不会 但是,请确保所有外部资源都已正确释放。例如,如果您打开一个文件,它可能会跳过通常关闭的位置。否。局部变量不需要单独清理。当堆栈

我有一个程序,在这个程序中,我需要打破一大堆嵌套的for循环。到目前为止,大多数人告诉我的方法是在我的代码中使用丑陋的goto

现在,如果我在循环中创建一组本地堆栈(我想这就是它们的名称,如果不是,我的意思是只使用常规变量而不使用新命令)变量,我的程序会点击触发goto的if语句,由于我的程序不正确地退出了许多循环,并且没有清理本地变量,我是否会遇到内存泄漏?

不,您不会


但是,请确保所有外部资源都已正确释放。例如,如果您打开一个文件,它可能会跳过通常关闭的位置。

否。局部变量不需要单独清理。当堆栈弹出时,所有局部变量都将随之消失。

否。您只能泄漏动态分配的内存

堆栈变量在您进入函数时定义(并分配),在您离开函数时隐式消除(因为整个调用堆栈记录被弹出)。函数内部的任何反弹都不可能对整个时间分配的内存造成任何破坏。无论代码的执行路径如何,当控件返回调用函数时,堆栈记录将弹出,内存将被释放。

Goto并不总是坏的,但在您的情况下,可能不应该使用Goto

参见goto和goto的良好使用示例

如果转到范围之外的标签,堆栈上的对象将被释放

例如:

#include <iostream>
using namespace std;

class A
{
public:
  ~A() 
  {
     cout<<"A destructor"<<endl;
  }
};



int main(int argc, char**argv)
{
  {
    A a;
    cout<<"Inside scope"<<endl;
    goto l;
    cout<<"After l goto"<<endl;
  }

  cout<<"Outside of scope before l label"<<endl;

l:
  cout<<"After l label"<<endl;
  return 0;
}
#包括
使用名称空间std;
甲级
{
公众:
~A()
{

cout不,您不会导致内存泄漏。使用
转到
并不是“不正确地退出循环”。从代码结构的角度来看,它只是一般不推荐使用


除此之外,当您离开循环时,局部变量将超出范围并从堆栈中弹出(即清理)在这个过程中。

不,如果使用goto语句中断循环,循环中的任何自动变量都不会导致编程泄漏。

其他答案是正确的……但是,如果必须以不同的方式嵌套循环,我会质疑将它们放在那里的设计。将该逻辑拆分为单独的函数将是一个赌注这是解决这样一个问题的最好办法

Billy3

堆栈变量(自动,而不是自动站)不像通过new()或malloc()分配的变量那样“泄漏”

至于gotos的“丑陋”,那只是教条。阅读Knuth,他和Dijkstra一样聪明。避免基于意大利面的编程,但小心使用不会退化为意大利面

Dijkstra不喜欢它们,因为gotos的大部分功能都可以通过其他结构化编程技术完成,并且使用的代码更少,因此使其他结构化编程更不容易出错


明白gotos不应该是你的第一个解决方案,也不要刻意使用它们,但如果有道理,不要屈服于教条的伦奇暴徒。break声明只是一个伪装的goto,专为严格遵守“你不应该使用gotos”的情况而设计这条命令毫无意义。

反向会导致资源泄漏吗?或者下面代码中的任何其他潜在问题

重新执行:

        try
        {
            //Setup request
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);

            ....

            //Get Response
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();

           if(response != HttpStatus.OK && noOfRetries < 3)
            {
                noOfRetries++;
                Thread.Sleep(10 * 1000);


                response.Close();
                goto Reexecute;
            }
            ...

            response.Close();
         }
         catch
         {

         }
试试看
{
//设置请求
HttpWebRequest请求=(HttpWebRequest)WebRequest.Create(url);
....
//得到回应
HttpWebResponse=(HttpWebResponse)request.GetResponse();
if(响应!=HttpStatus.OK&&nofretries<3)
{
noOfRetries++;
线程。睡眠(10*1000);
response.Close();
去重新执行;
}
...
response.Close();
}
抓住
{
}

Goto有什么不对吗?是的,只有跳转不是坏事。我喜欢它们比在每个循环中检查变量要好得多。它们对C中的错误处理函数出口也非常好。如果你对零分的东西做出反应,那么你可能会考虑抛出一个异常。也许我有点苛刻。评论。我承认可能有几个小标题是“代码> Goto 不太有害。但是我想引用这个答案中的第一个注释:”+ 1:如果它足够复杂,可以考虑GOTO,它就足够复杂了,封装在一个函数中,避免GOTO。把
return
想象成一个结构化的
goto
。如果
return
会泄漏,那么
goto
也会泄漏。(你在这方面,考虑使用结构化方法而不是意大利面,将代码放入自己的函数中,使用<代码>返回< /代码>。是的,但是如果我不使用函数会发生什么?如果我在主程序中使用goto同时中断许多循环,这也是真的吗?所有内容都在函数中,即使该函数是main()。main()的堆栈记录当程序启动时分配,在程序结束时被丢弃——与任何其他函数相同的规则。在C++和C中,代码总是在一个函数或另一个函数中运行。当然。那不是真的:变量在整个“作用域”中从堆栈上弹出。看看这段代码:是的,我也质疑我使用5D数组的逻辑,但什么是有效的,有效的。我不知道,整个程序从一开始就是一个巨大的循环,它只是在一组数据上不断循环做一大堆事情。天哪。。。一个5D数组?我唯一的理由是在PHP中,数组和对象在数据存储方面可能是一样的。。。