Проблема с putenv () в UNIX при использовании free () - PullRequest
2 голосов
/ 09 сентября 2010

Я пытаюсь использовать putenv () в UNIX, объединяя str1 и str2 перед этим. Я хочу добавить переменную или изменить переменную в среде, поэтому я вызываю putenv () (или я мог бы вызвать setenv () идентично).

Обычно я получаю str1 и str2, я создаю str1 = str2 и передаю его в putenv () в качестве параметра.

Код, который я показываю, работает, но когда я раскомментирую вызов free (), он этого не делает: переменная не добавляется / не изменяется для среды.

size_t size = strlen(str1) + strlen(str2) + 2; // 2 is for the '\0' and the '='
char *tmp = (char *) malloc(sizeof(char) * size);
char *p;
int pos = 0;

// Copy first word
p = str1;
while (*p != NULL) {
    tmp[pos++] = *p++;
}

// Add the '='
tmp[pos++] = '=';

// Copy second word
p = str2;
while (*p != NULL) {
    tmp[pos++] = *p++;
} 

// Add null character
tmp[pos] = '\0';

int ret = putenv(tmp);
if (ret != 0) {
    perror("putenv failed");
}

//free(tmp); // This line is the problem when not commented

Я прошу прощения за избыточность кода, я знаю, что два цикла while идентичны. Проблема, с которой я столкнулся, заключается в том, что если я раскомментирую бесплатное утверждение, а затем вызову «env» для печати окружения, putenv не добавит значение.

Я не уверен, почему это так. Прямо сейчас, чтобы это работало, у меня утечка памяти, которая мне не нравится. Когда я использовал массив, а не указатель, он вызывал ту же проблему, что и свободный комментарий.

Есть идеи?

1 Ответ

4 голосов
/ 09 сентября 2010

putenv () требует наличия строки, заданной в среде, поскольку она не копирует строку; он использует указатель на строку, предоставленную для аргумента.

Это отмечается в описании OpenGroup putenv () довольно расплывчато:

http://www.opengroup.org/onlinepubs/009695399/functions/putenv.html

"Потенциальная ошибка - вызвать функцию putenv () с автоматической переменной в качестве аргумента, а затем вернуться из вызывающей функции, пока строка все еще является частью среды."

Два возможных решения вашей проблемы:

1 - Чтобы получить то, что вы хотите, с помощью putenv (), вы можете использовать статическую строку или иным образом использовать строку, которая не выходит за рамки видимости, пока переменная окружения не будет ненужной.

2 - в качестве альтернативы используйте setenv (const char * envname, const char * envval, int overwrite), который проще в использовании, чем putenv, выделяет память и копирует строку, и не требует объединения строк, как вы делаю прямо сейчас.

...