2015-05-26 3 views
1

Как требуется 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 точку в строке, которые проходят к нему.

ответ

1

В вашем случае это не обязательно, если вы не планируете очень часто устанавливать переменные среды, что приводит к исчерпанию ресурсов памяти.

Но было бы здорово, если бы вы всегда освобождали ресурсы после того, как вы закончите с их использованием, будь то файловые дескрипторы/память/мьютексы. Поступая таким образом, вы не будете ошибаться при создании серверов.

Ожидается, что некоторые серверы будут работать 24x7. В таких случаях любая утечка любого типа означает, что ваш сервер в конечном итоге исчерпает этот ресурс и каким-то образом зависает. Короче говоря, полезная программа, и утечка не так уж плоха. Любой сервер, любая утечка - смерть. Сделай себе одолжение. Очистите себя. Это хорошая привычка

+0

Итак, мне нужно отслеживать новые переменные, которые я добавил вручную, чтобы я мог освободить его, как только мне это больше не нужно? Мне интересно, как они реализуют его в исходном коде Linux, чтобы избежать утечки памяти ... –

+0

Отличный способ сделать это - не бросать вызовы в malloc() и free() по всей вашей кодовой базе. Централизовать их на две функции, тогда у вас есть одна точка для всех проверок, которые также делают счет. Подробный пример можно найти здесь. http://stackoverflow.com/a/2983953/2959769 –

Смежные вопросы