Программирование на C - вернуть указатель на Freed - PullRequest
3 голосов
/ 06 августа 2010

У меня есть функция, foo (), которая выделяет память и возвращает ее. Это стандартная практика для меня, чтобы освободить его в конце моей основной функции?

char* foo(){
 char * p;

 p = malloc(sizeof(char) * 4); /* edit - thanks to msg board */
 p[0] = 'a';
 p[1] = 'b';
 p[2] = 'c';
 p[3] = '/0'; /* edit: thanks to the msg board. */

 return p;
}

int main(int argc, char *argv[])
{
 char * p2;

 p2 = foo();

 printf("%s", p2);    

 free(p2);

 return 0;
}

Ответы [ 8 ]

6 голосов
/ 06 августа 2010

Освобождение в конце main() будет правильным решением, да.Вы можете думать о нулевом завершении этой строки, хотя.Более идиоматический дизайн предназначен для всего управления памятью, так сказать, «на одном уровне».Что-то вроде:

void foo(char *p)
{
  p[0] = 'a';
  p[1] = 'b';
  p[2] = 'c';
  p[3] = '\0';
}

int main(int argc, char **argv)
{
  char *p2 = malloc(4);
  foo(p2);
  printf("%s", p2);
  free(p2);
  return 0;
}
1 голос
/ 06 августа 2010

«Стандартная практика», если есть такая вещь, состоит в том, чтобы освободить память, как только вы закончите с ней.

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

0 голосов
/ 06 августа 2010

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

  • Будьте проще: для каждого malloc должно быть соответствующее free. Основное преимущество заключается в том, что если вы когда-нибудь захотите преобразовать свою автономную программу в компонент более крупной программы, ваша main превратится в библиотечный вызов, и потребуются вызовы free.

  • Проще говоря: освобождение ресурсов программы - это работа ОС. Это правильная стратегия управления - память программы представляет собой область памяти, которая освобождается одним махом при выходе из программы. Основное преимущество заключается в том, что вам не нужно отслеживать каждый выделенный блок, что иногда бывает сложно (но тогда вы можете рассмотреть возможность сбора мусора).

0 голосов
/ 06 августа 2010

Одна из веских причин сделать это, чтобы у вас были совпадения с malloc / free. Если код перемещается, программист, естественно, будет искать свободное совпадение с malloc. Если его там нет, это может привести к путанице (но, надеюсь, ненадолго).

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

0 голосов
/ 06 августа 2010

Я бы подумал, что лучше распределить и освободить память в одной и той же функции (в данном случае main ()).

Например:

void foo(char *p)
{     
 p[0] = 'a';
 p[1] = 'b';
 p[2] = 'c';

 return ;
}

int main(int argc, char *argv[])
{
 char * p2;

 p = malloc(sizeof(int) * 3);
 foo(p2);

 printf("%s", p2);    

 free(p2);

 return 0;
}
0 голосов
/ 06 августа 2010

а зачем вам malloc (sizeof (int) * 3), когда вы выделяете 3 символа?

0 голосов
/ 06 августа 2010

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

И ДА, это хорошая практика - освобождать его, когда вы его используете, даже если программа выходит из следующей строки.

0 голосов
/ 06 августа 2010

Я не знаю, является ли это "стандартной практикой", но free() необходим, или вы потеряете память.

Я бы сделал две функции, new_foo() и delete_foo(), например:

char* new_foo()
{
    char * p;
    p = malloc(sizeof(int) * 4);
    /* ... */
    return p;
}

void delete_foo(char* p)
{
    free(p);
}

int main()
{
    char * p2;
    p2 = new_foo();
    /* ... */
    delete_foo(p2);
    return 0;
}

На мой взгляд, это "имеет больше смысла".

...