Будет ли использование 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
         {

         }