Методы, чтобы обернуть getenv () и аналогичные без утечек или условий гонки в C - PullRequest
0 голосов
/ 26 ноября 2018

Указатель, возвращаемый getenv, не должен храниться, так как будущие вызовы getenv могут изменить его (или вызовы setenv и т. Д.).Я пытаюсь написать вспомогательную оболочку для getenv, которая возвращает значение по умолчанию, если переменная окружения не найдена.Я бы предпочел не пропускать память.

Опции, о которых я думал:
Пусть функция-обертка скопирует строку, возвращаемую getenv, используя malloc и strcpy или strdup (это в POSIX-совместимой системе).Это работает и позволяет обрабатывать ошибки, но требует, чтобы вызывающая сторона помнила, чтобы освободить указатель.Это создает пространство для утечки памяти.
Не пытайтесь кэшировать значение, пусть каждый вызывающий объект делает это.Это позволяет легко оставить условие гонки. Используйте глобальную переменную для хранения копии строки, возвращаемой getenv.Это избавило бы от необходимости вызывать вызовы для освобождения памяти вызывающими программами, но могло бы привести к возникновению состояния гонки, как и в случае с getenv, если только я не добавлю какие-либо блокировки / атомарные обновления.
Используйте статическую переменную в функции для кэширования значения.Это, вероятно, лучший вариант, так как он повторно использует память для последующих вызовов, но может привести к условиям гонки.

Я вполне уверен, что что-то упустил.

1 Ответ

0 голосов
/ 27 ноября 2018

Это не так:

Указатель, возвращаемый getenv, не должен сохраняться, поскольку будущие вызовы getenv могут его изменить

Следующее:

(или звонки в setenv и т. Д. *

Однако, здесь сделан вывод, что вы не можете использовать setenv (или что-либо, что изменяет среду)в многопоточном процессе. Это также делает потокобезопасной любую стандартную функцию, которая использует среду.

Итак, используйте getenv и обработайте строки, на которые указывают возвращаемые значения, как неизменяемые.

...