Будет ли использование goto причиной утечки памяти?
У меня есть программа, в которой мне нужно вырваться из большой группы вложенных циклов. До сих пор, как многие люди говорили мне сделать это, нужно использовать уродливые goto в моем коде.
Теперь, если я создаю кучу локального стека (я думаю, что то, что они называются, если нет, я имею в виду только обычные переменные, не использующие новую команду) переменные внутри моих циклов, и моя программа попадает в ту, что оператор if, который запускает goto, я столкнулся с утечкой памяти из-за того, что моя программа вышла из многих циклов неправильно и не очистила локальные переменные?
Ответы
Ответ 1
Нет, вы не будете вызывать утечку памяти. Использование goto
не является "отсутствием циклов". Он просто обычно не рекомендуется из кодовой структуры точки зрения.
В стороне, когда вы покидаете цикл, локальные переменные выходят из области действия и выгружаются из стека (то есть очищаются) в процессе.
Ответ 2
Переменные стека (авто, а не автоботы) не являются "негерметичными", как переменные, выделенные через new() или malloc().
Что касается "уродства" готосов, которые просто догматичны. Прочитайте Кнута, он был так же блистателен, как Дейкстра. http://pplab.snu.ac.kr/courses/adv_pl05/papers/p261-knuth.pdf Избегайте программирования на основе макаронных изделий, но осторожное использование не деградирует в спагетти.
Dijkstra не понравилось им ПОТОМУ ЧТО большая часть того, что вы можете делать с gotos, может быть выполнена с использованием других методов структурированного программирования и использует меньше кода, что делает другую структуру менее подверженной ошибкам.
Поймите, что gotos не должны быть вашим первым решением и не изо всех сил пытаться их использовать, но если это имеет смысл, не подчиняйтесь догматическим толстякам. Заявление о перерыве - это просто переодетый goto, предназначенный для случаев, когда строгое прикосновение к заповеди "Ты не должен использовать gotos" не имеет смысла.
Ответ 3
Нет. Вы можете только утечка памяти, которая динамически распределяется.
Ответ 4
Переменные стека определяются (и выделяются) с момента ввода функции и неявно устраняются в тот момент, когда вы покидаете функцию (так как вся запись стека вызовов удаляется). Никакое количество отскоков внутри функции не может привести к хаосу с памятью, которая была выделена все время. Независимо от того, какой путь выполнения вы выполняете через код, запись стека появится, когда управление вернется к вызывающей функции, и память будет освобождена.
Ответ 5
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;
}
Это напечатает:
Внутренний масштаб
Деструктор
После l label
Ответ 6
Другие ответы верны.... однако, если вам нужно развернуть петли по-другому, я бы поставил под сомнение дизайн, который их разместил. Разделение этой логики на отдельные функции было бы лучшим способом решения такой проблемы.
Billy3
Ответ 7
Нет, не будешь.
Однако убедитесь, что все внешние ресурсы правильно выпущены. Например, если вы открыли файл, можно было бы перейти назад, где он обычно закрывается.
Ответ 8
Неа. Локальные переменные не нуждаются в индивидуальной очистке. Когда стек появляется, все локальные переменные уйдут прямо вместе с ним.
Ответ 9
Нет, никакие автоматические переменные в ваших циклах не вызовут утечек программирования, если вы выйдете из ваших циклов с помощью инструкции goto.
Ответ 10
Будет ли доступ к ресурсам утечки обратно? Или любые другие потенциальные проблемы с кодом ниже?
повторно выполнять:
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
{
}