2010-08-06 2 views
3

У меня есть функция foo(), которая выделяет память и возвращает ее. Является ли стандартной практикой для меня освобождать ее в конце моей основной функции?C Программирование - Return Pointer to Freed

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; 
} 
+0

Обратите внимание, что это проблема стиля: если не освобождена, она будет возвращена ОС после выхода. Наверное, лучше делать в основном, но не обязательно. –

+5

Я всегда предпочитал освобождать его до выхода, если тело вашей основной функции позже перемещено или скопировано. Кроме того, я понимаю, что это всего лишь пример, но если вы делаете что-то подобное, вы можете посмотреть на strdup. –

ответ

6

Освобождение в конце 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; 
} 
+0

Подумайте, там есть опечатка, вы хотите: 'void foo (char * p)' –

+0

Упс, спасибо @Justin. Фиксация сейчас. –

+0

Спасибо, Карл. Есть ли какая-то заслуга в моей функции foo, которая не имеет состояния, то есть функциональна? –

0

Я не знаю, если это «стандартная практика», но free() необходимо или будет протекать Memeory.

Я хотел бы сделать две функции, 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; 
} 

Это "имеет смысл", на мой взгляд.

+3

Мы говорим о последней строке функции 'main()'. Это вряд ли подходит для утечки памяти, так как все ресурсы все равно будут возвращены в систему. – Bolo

+0

'sizeof (int) * 3' ->' sizeof (char) * 4' –

+0

@Bolo: По-прежнему хорошая практика для очистки после себя. В конце концов, что, если система не восстанавливает утечку ресурсов? Язык C не дает никаких гарантий, что запрашиваемые ресурсы запрашиваются при выходе из вашей программы. –

0

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

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

+0

Освобождение всех ресурсов от конца программы - это функция ОС, а не функция C-среды. Это более-менее стандартно в современных ОС, но это не требуется для среды C. –

+0

Ну да, я упомянул, что, поскольку программа, которая не освобождает память, приведет к утечке памяти, если она работает вечно. Но этот пример завершается, и, следовательно, я добавил эту точку. –

0

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

+0

Я только что заметил свою ошибку. Спасибо –

1

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

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

0

Я бы подумал, что было бы лучше распределить и освободить память в той же функции (в данном случае 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

за исключением (в реальном мире) вы почти наверняка не будете знать, сколько памяти для malloc до фактического вызова – KevinDTimm

0

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

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

0

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

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

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