char *를 리턴해 주는 C 함수들의 메모리 관리는?
글쓴이: Viz / 작성시간: 토, 2003/12/13 - 3:30오전
char *를 리턴해주는 함수들은 무지 많지요.
기본 C 라이브러리에 있는 strcat, strdup 같은 스트링 관련 함수에서 부터..
ctime같은 편한 녀석들도 있구요.
그런데 언제나 궁금한 것이.. 이렇게 받은 char *에 대해 과연 free를 해주어야 하는가.. 랍니다.
분명히 strdup 같은 경우에는 malloc으로 할당되기 때문에 free를 하라는 지시가 man page에 존재합니다.
그런데 ctime 이란 함수의 경우에는 어떨까요?
char *ctime(const time_t *timep);
man page에는 free에 관련된 이야기가 전혀 없네요.
저의 생각으로는 아마 함수 내부에 static으로 선언된 buffer가 존재한다.. 일 껏 같은데요.
그럼 생기는 문제가 있죠. thread unsafe할 것이라는 것..(당연한건가요?)
흐음.. 이런 ctime처럼 특별한 언급이 없다면 저는 언제나 할당된 메모리는 free할 필요가 없고, 해서도 안된다.. 라는 입장이긴 합니다만.. 한 후배가 자신은 free()를 해왔다고 해서.. 당황스럽네요.. ;;
어떻게 하는 것이 정석인가요? :D
Forums:
free를 해줘야 합니다 =3=33
free를 해줘야 합니다 =3=33
오랫동안 꿈을 그리는 사람은 그 꿈을 닮아간다...
http://mytears.org ~(~_~)~
나 한줄기 바람처럼..
내부에 static 하게 잡힌 주소를 리턴합니다. free 하실 필요는
내부에 static 하게 잡힌 주소를 리턴합니다. free 하실 필요는 없습니다. 그리고 thread safe를 원하시면 ctime_r 을 사용하시면 됩니다.
맨페이지를 좀 더 열심히 읽어봐주세요 8) 거의 다 나옵니다. ct
맨페이지를 좀 더 열심히 읽어봐주세요 8)
거의 다 나옵니다. ctime같은 것은 당연히 나옵니다.
저도 궁금했었는데... ㅡㅡ;위에 둘중 어느 분의 말을 따라야 할
저도 궁금했었는데... ㅡㅡ;
위에 둘중 어느 분의 말을 따라야 할까요?
저는 예전에 대충 테스트해본 결과... 두번째분 말씀이 맞는 듯한데..
모르겠습니다..
----
먼저 알게 된 것을 알려주는 것은 즐거운 일이다!
http://hangulee.springnote.com
http://hangulee.egloos.com
man ctime의 마지막 부분.[code:1]NOTES
man ctime의 마지막 부분.
함수마다 다르며, 어떤 함수가 malloc된 buffer를 넘기는지 확인
함수마다 다르며, 어떤 함수가 malloc된 buffer를 넘기는지 확인해서 사용해야합니다.
정말 귀찮은 일이죠....
---
http://coolengineer.com
특별한 언급이 없으면 static 할당된 메모리를 리턴합니다.윗
특별한 언급이 없으면 static 할당된 메모리를 리턴합니다.
윗 분들 중 "free()를 해 줄 필요가 없다"란 말씀을 하셨는데, static으로 잡힌 경우 "free()를 하면 안된다. 큰일난다"로 표현하는게 나을 듯 싶군요. strdup()을 제외하고, malloc()한 memory를 돌려주는 함수는... 흠.. 지금 기억으론 없는 것 같군요.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Korean Ver: http://cinsk.github.io/cfaqs/
답변해 주셔서 감사합니다.후배 녀석 다시 교육시켜야겠네요. :)
답변해 주셔서 감사합니다.
후배 녀석 다시 교육시켜야겠네요. :)
My Passion for the Vision!
char* strcat( char* dest, const char* sr
char* strcat( char* dest, const char* src );
결과적으로 strcat은.. dest를 리턴해주지 않던가요 +_+?
그랬던거 같은데.. 앗 그러고보니 저것도 내부적으로 malloc하는건 아니군요 =3=33
생각없이 glib에 있는 것들 생각하고 free해야 한다고 달아버렸네요 =3=3
오랫동안 꿈을 그리는 사람은 그 꿈을 닮아간다...
http://mytears.org ~(~_~)~
나 한줄기 바람처럼..
당연히 프리하면안되죠..조금 생각해보면.. 해야할지 안해도 될지
당연히 프리하면안되죠..
조금 생각해보면.. 해야할지 안해도 될지 구분이 갑니다.
물론 확힐한건 스펙을 확인해보고 사용해야겠지만...
strdup같은경우 불특정한 길이를 계속적으로 복사할필요가 있죠.. 그러면 이것이 내부 static 변수로 리턴할리가 있겠어요..ㅋㅋ
ctime 같은경우 겨우 날짜스트링을 반환하는데 내부에서 alloc 한다는건 너무무겁다는생각이 들죠.. 더구나 날짜 스트링은 그크기가 변할필요가 없습니다.
고정길이라는거죠..
----------------------------------------------------------------------------
free 에 신경쓰실 필요 없습니다.
정확하게 구현되어 있는 소오스를 들여다 본것은 아니고, 운영체제마다 조금씩 다를수 있지만, 이런식의 함수를 호출해서 사용할 경우에는 일단 free 보다도 그 메모리의 데이터가 유지되어 있는것에 대하여 신경을 쓰실필요가 있습니다.
일단 함수가 호출되면, 그 데이터는 HEAP 의 임시영역에 잡힙니다. 그리고 데이터가 만들어지고, HEAP 영역의 데이터 포인터를 리턴하고 종료합니다. 즉 이미 free() 가 된것과 마찬가지의 상태입니다.
그런데 이렇게 HEAP 영역에 잡힌 데이터 영역은 그 함수의 사용이 종료되면 사실 시스템에 반환됩니다. 반환된다고 하면, 데이터가 잃어버릴 염려가 있을지도 모르겠지만, 여기서 주의해야 할 요건이 생기는 것입니다.
HEAP 영역의 메모리가 시스템에 반환 되었다고 하더라도 그 프로세서 가 종료된것은 아니므로, 그 메모리는 계속 그 프로세서가 사용할수 있습니다. 따라서 그다음의 조작에 영향을 받습니다. 다른 함수를 호출하여 그 HEAP 공간을 사용하게 되면 그 데이터는 거의 깨진다고 봐야 합니다.
그러므로 함수를 호출하기전에 데이터를 자신의 메모리 영역으로 옮겨놓는것이 필요할수 있습니다. 포인터 함수이므로 strcpy, memcpy 등으로 옮길수 있는데, 이런함수는 매크로 수준이거나, 함수가 호출되어도 HEAP 공간을 거의 사용하지 않으므로 데이터를 이용할 수 있습니다.
그러나 좀더 복잡한 함수, 예를 들면 printf 같은 것을 호출하면 이때는 거의 100% 깨집니다. 따라서 보통 printf ("%ld%, ctime()) 같은 것은 사용하면 안됩니다. 거의 세그멘테이션 폴트가 발생할것 입니다.
좀 정리가 되셨는지요.
- 겨울아찌 -
- 겨울아찌 -
winchild@gmail.com
[quote="winchild"]정확하게 구현되어 있는 소오스를 들여다
static 변수는 데이타 영역에 저장됩니다. 그리고 HEAP 영역의 변수는 함수의 사용이 종료된다고 해서 메모리가 반환되지는 않습니다. 반드시 free 해야 합니다. 스택영역과 혼돈하신 듯 합니다.
따라서,
printf("%ld",ctime());
는 Segmentation fault를 일으키지 않습니다.
Re: free 에 신경쓰실 필요 없습니다.
...
지금까지 나온 내용대로라면 역시 함수 내에 static으로 잡혀 있는 것
지금까지 나온 내용대로라면 역시 함수 내에 static으로 잡혀 있는 것이고, 이는 메모리에서는 아마 bss 영역에 잡혀 있겠지요.
이부분은 function call과는 전혀 관계없이 process가 메모리에서 제거 될 때 까지 유지된답니다.
그럼~
My Passion for the Vision!
쯧! 논쟁하자는 것은 아니지만...
ctime() 라이브러리의 함수 소오스를 찾아서 확인해 봐야 겠지요.
그 소오스내에서 리턴하는 변수부분을 static 으로 잡았으면 함수가 종료되도 메모리가 해제되지 않을것 이구요. dynamic 이면 (static 프리픽스가 없다면) 종료시에 해제되겠지요.
이것은 여러 UNIX 운영체제 프로그램을 사용해보면서 격었던 경험담에서 추측한것 이니까. 딱히 printf ("%s",ctime()); 이 종료되지 않는다고 단정할수는 없겠지요. (실제 세그멘테이션 폴트를 경험한적이 있다는 것을 말하는 것입니다.)
그리고 HEAP 과 STACK 의 구분은 어쨌든 임시공간이라는 것은 의미가 같겠지요?
- 겨울아찌 -
- 겨울아찌 -
winchild@gmail.com
HEAP 과 STACK 이 임시영역이라...
위에서 쓰신 말씀중에.. 호출된 함수 내부에서 할당한 HEAP의 영역은 함수가 리턴되면 자동으로 반환된다..라고 쓰셨는데..이건 제가 아는 상식으로는 말이 안되는 얘기입니다. 함수가 리턴되면서 반환되는것은 해당 함수가 호출되면서 쌓인 STACK AREA 입니다. HEAP은 절대로..자동 반환되지 않습니다. HEAP은 해당 프로세스가 종료할때까지 계속 존재하며, 명시적으로 free 하지 않으면 계속 할당된 상태로 남아 있게 됩니다. HEAP과 STACK 은 임시공간이다..라고 같이 넘어갈 성질은 전혀 아닙니다. HEAP은 임시공간이 아닙니다.
너무 오래된 글이라 답글 다는것도 민망합니다만. 다시한번 알아보시기 바랍니다.
libc의 ctime 구현
구현에 따라 달라지겠지만, 전통적으로 reentrant하지 않는 형태로 구현된것은 static에,
만일 reentrant하도록 만들어졌다면, heap에 할당하고 그 주소를 thread specific data에 넣어 관리할 것입니다.
아래는 대표적인 두 OS의 libc 소스입니다. 둘다 static 입니다.
ctime은 다른 socket 계열 함수와 달리 아직은 reentrant를 지원하지 않는 군요.
Free BSD
http://www.freebsd.org/cgi/cvsweb.cgi/src/lib/libc/stdtime/localtime.c?rev=1.36&content-type=text/x-cvsweb-markup
http://www.freebsd.org/cgi/cvsweb.cgi/src/lib/libc/stdtime/asctime.c?rev=1.11&content-type=text/x-cvsweb-markup
Linux.. glibc
http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/time/ctime.c?rev=1.5&content-type=text/x-cvsweb-markup&cvsroot=glibc
http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/time/asctime.c?rev=1.15&content-type=text/x-cvsweb-markup&cvsroot=glibc
---
http://coolengineer.com
함수마다
함수마다 달라요...;;
어떤건 static, 어떤건 heap... heap으로 되는 녀석들 같은경우 man page에서 친절하게 반드시 free를 해야된다고 나와있습니다. static인 녀석들도 나와있지요...멀티스레드 환경하에서는 static으로 되는 녀석들은 호출하기 안좋지요.
------------------------------------------
Let`s Smart Move!!
http://kalstein.tistory.com/
댓글 달기