Как требуется TLPI exercise 6-3
, я сделал реализацию setenv()
и unsetenv()
с использованием putenv()
, getenv()
и с помощью модификации environ
переменной напрямую.c - unsetenv() реализация, нужно ли освобождать память?
Код:
// setenv()/unsetenv() impl
// TLPI exercise 6-3
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#define ENV_SEP '='
extern char **environ;
// setenv() impl using putenv() & getenv()
int setenv_impl(const char * name , const char * value , int overwrite) {
if(!overwrite && getenv(name)) { // exists & don't overwrite
return 0;
} else {
// construct the new variable
char *env_var = malloc(strlen(name) + strlen(value) + 2);
strcpy(env_var, name);
env_var[strlen(name)] = ENV_SEP;
strcpy(env_var+(strlen(name)+1), value);
int result = putenv(env_var);
if(result==0) {
return 0;
} else {
errno = result;
return -1;
}
}
}
// unsetenv() impl via modifing environ directly,
int unsetenv_impl(const char * name) {
char **ep, **sp;
size_t len;
len = strlen(name);
for(ep = environ; *ep != NULL;) {
if(strncmp(*ep, name, len)==0 && (*ep)[len] == ENV_SEP) {
// shift all successive elements back 1 step,
for(sp=ep; *sp != NULL; sp++) {
*sp = *(sp+1);
}
} else {
ep++;
}
}
return 0;
}
// setenv_impl() test
int setenv_impl_test() {
char *key = "name";
setenv_impl(key,"Eric", 1);
printf("%s\n", getenv(key));
setenv_impl(key,"Eric2", 0);
printf("%s\n", getenv(key));
setenv_impl(key,"Eric3", 1);
printf("%s\n", getenv(key));
return 0;
}
// unsetenv_impl() test
int unsetenv_impl_test() {
char *key = "name";
setenv_impl(key,"Eric", 1);
printf("%s\n", getenv(key));
unsetenv_impl(key);
char *val = getenv(key);
printf("%s\n", val==NULL?"NULL":getenv(key));
return 0;
}
int main(int argc, void *argv[]) {
// setenv_impl_test();
unsetenv_impl_test();
return 0;
}
В моей setevn_impl()
, я использую malloc()
выделить память для новой переменной окружения.
Но я не знаю, как распределена память среды по умолчанию процесса.
Мой вопрос:
В моей
unsetenv_impl()
реализации, это necesary/собственно освободить память удаленной строки окружения с помощьюfree()
?Если я не освобожу его, это будет проблема, или она не займет много памяти, поэтому ее можно игнорировать?
Совет:
putenv()
не будет дублировать строку, это просто сделать глобальную переменную environ
точку в строке, которые проходят к нему.
Итак, мне нужно отслеживать новые переменные, которые я добавил вручную, чтобы я мог освободить его, как только мне это больше не нужно? Мне интересно, как они реализуют его в исходном коде Linux, чтобы избежать утечки памяти ... –
Отличный способ сделать это - не бросать вызовы в malloc() и free() по всей вашей кодовой базе. Централизовать их на две функции, тогда у вас есть одна точка для всех проверок, которые также делают счет. Подробный пример можно найти здесь. http://stackoverflow.com/a/2983953/2959769 –