我有一个程序,我需要打破一大堆嵌套for循环。到目前为止,大多数人告诉我这样做的方式是在我的代码中使用一个丑陋的goto。
现在,如果我创建了一堆本地堆栈(我认为这就是它们被称为,如果没有,我的意思是只是常规变量而不使用新命令)我的循环中的变量和我的程序命中一个if语句触发goto,由于我的程序不正确地退出许多循环并且没有清理局部变量,我会遇到内存泄漏吗?
答案 0 :(得分:20)
不,您不会导致内存泄漏。使用goto
并非“不正确地退出循环”。从代码结构的角度来看,它只是通常不推荐。
除此之外,当你离开循环时,局部变量将超出范围并在过程中弹出堆栈(即清理)。
答案 1 :(得分:5)
堆栈变量(autos,而不是autobots)不像通过new()或malloc()分配的变量那样“漏洞”。
至于那些只是教条的“丑陋”。阅读Knuth,他和Dijkstra一样出色。 http://pplab.snu.ac.kr/courses/adv_pl05/papers/p261-knuth.pdf避免使用面食编程,但小心使用不会降低为意大利面。
Dijkstra不喜欢他们,因为你可以用其他结构化编程技术完成大部分你可以做的事情,并且使用更少的代码,因此使得其他结构更不容易出错。
明白不应该是你的第一个解决方案,并且不要忘记使用它们,但如果它有意义,就不要服从教条式的怪物小怪。破坏声明只是一个伪装的转换,专为严格遵守“你不应该使用”的诫命没有意义的情况而设计。
答案 2 :(得分:2)
没有。您只能泄漏动态分配的内存。
答案 3 :(得分:2)
堆栈变量在您进入函数时被定义(和分配),并且在您离开函数时被隐式消除(因为整个调用堆栈记录被弹出)。在函数内部没有任何反弹可能会导致对整个时间内分配的内存造成任何破坏。无论您通过代码执行什么路径,当控制返回到调用函数时,堆栈记录都会弹出,并且内存将被释放。
答案 4 :(得分:1)
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;
}
这将打印:
内部范围
析构函数
贴上标签后
答案 5 :(得分:1)
其他答案都是正确的......但是,如果你必须以不同方式嵌套循环,我会质疑将它们放在那里的设计。将该逻辑拆分为单独的函数将是解决此类问题的更好方法。
Billy3
答案 6 :(得分:0)
不,你不会。
但是,请确保正确释放所有外部资源。例如,如果您打开文件,则可以跳过通常关闭的位置。
答案 7 :(得分:0)
不。局部变量不需要单独清理。当堆栈弹出时,所有局部变量都会随之消失。
答案 8 :(得分:0)
不,如果使用goto语句中断循环,循环中的任何自动变量都不会导致编程泄漏。
答案 9 :(得分:0)
向后转到资源泄漏?或以下代码的任何其他潜在问题?
重新执行:
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
{
}