Бизон - таблица символов - соответствие бесплатно для malloc - PullRequest
0 голосов
/ 28 марта 2019

Я рассматриваю пример mfcalc в руководстве Bison, и у меня возник вопрос о таблице символов.

В частности, в подпрограмме putsym() у нас есть вызовы malloc, но я не вижу соответствующего вызова free. Нужно ли нам освобождать таблицу символов (sym_table в следующем коде) вручную или инструмент позаботится об этом автоматически?

symrec *
putsym (char const *sym_name, int sym_type)
{
  symrec *ptr = (symrec *) malloc (sizeof (symrec));
  ptr->name = (char *) malloc (strlen (sym_name) + 1);
  strcpy (ptr->name,sym_name);
  ptr->type = sym_type;
  ptr->value.var = 0; /* Set value to 0 even if fctn.  */
  ptr->next = (struct symrec *)sym_table;
  sym_table = ptr;
  return ptr;
}

1 Ответ

2 голосов
/ 29 марта 2019

«Инструмент» ничего не знает о том, что делают ваши действия.

Я процитировал «инструмент», потому что на самом деле в большинстве проектов синтаксического анализа задействованы как минимум два инструмента генерации кода: генераторы парсера (бизон).в данном случае) и генератор сканера ((f) lex, возможно).В примере mfcalc используется собранный вручную лексер, чтобы избежать зависимости от lex, хотя, вероятно, было бы проще использовать (f) lex.В любом случае, единственные вызовы библиотеки таблиц символов находятся в сканере и не имеют абсолютно никакого отношения к сгенерированному бизоном коду.

Конечно, в игре есть и другие инструменты.Например, весь проект построен с помощью компилятора C и выполняется внутри некоторой размещенной среды (если использовать слова стандарта C);другими словами, операционная система и библиотека поддержки времени выполнения, которая включает в себя реализации malloc и free (хотя, как вы отмечаете, free нигде не вызывается в примере кода).

Я упоминаюэто последнее, потому что они имеют отношение к вашему вопросу.Когда процесс завершается, все ресурсы процесса освобождаются, включая его образ памяти.(Это не требуется стандартом C, но почти все размещенные среды работают таким образом.) Таким образом, вам не нужно выделять free() памяти, если она будет использоваться до завершения программы.

Как и глобальные переменные, невыпущенное распределение памяти было довольно распространенным в свое время.В наши дни такие вещи считаются плохой практикой (в лучшем случае), и большинство программистов избегают их, но это было не всегда так.Было время, когда многие программисты считали расточительным отслеживать ресурсы только для того, чтобы освободить их непосредственно перед завершением программы, или перепрыгнуть через обручи, необходимые для гарантированного выполнения очистки перед завершением.(Даже сегодня многие программисты просто вставляют вызов exit(1), когда возникает неисправимая ошибка, вместо того, чтобы пытаться отследить и вручную освободить каждый выделенный блок памяти. Особенно в непроизводственном коде.)

Независимо от того, одобряете ли вы этот стиль кодирования или нет, примеры в руководстве по бизонам (и многие другие примеры кода всех видов) относятся ко времени этого невинного времени.

Таким образом, верно, что записи таблицы символовв этом примере никогда не освобождаются.Ваш производственный код, вероятно, должен работать лучше, но он также должен использовать более эффективную структуру данных и избегать зависимости от (одного) глобального контекста.Но это не имеет ничего общего с особенностями бизонов, которые mfcalc пытается проиллюстрировать.

...