char* 를 리턴하는 함수 본문

IT/C

char* 를 리턴하는 함수

previc 2018. 6. 12. 14:53


출처 : https://kldp.org/node/19320




먼저

1. 함수안에서

char *name = "KLDP";
char name[] = "KLDP";

가 어떻게 다른지 ? 제가 이해하기로는

name[] 은 KLDP를 위한 메모리가 할당되고 바로 그 주소를 가리키지만
return을 해도 그 메모리는 함수종료시 메모리 반환이 되므로 warning이고

*name 은 메모리 어딘가에 "KLDP" 를 할당하고 그 시작점을 가리키는
포인터를 선언하고 그 주소를 넘겨주므로
(어딘가에 선언된 "KLDP"는 함수가 끝나도 유효)
함수가 종료하면서 *name이 반환되더라도 이미 return값으로
그 주소를 넘겼으므로 참조할수 있다

인데 맞나요 ?
그렇다면 어딘가에 선언된 "KLDP"는 언제 메모리가 반환되나요 ?
프로그램 종료시 ?

그리고 방준영님의 방법론에서 dynamic allocation에서는
언제 alloc된 메모리를 free시켜야 하나요 ?
프로그래머가 더이상 필요가 없다고 판단되는 시점/루틴에서
free 시키면 되나요 ?
free를 따로 안시키면 프로그램 종료시에 자동 소멸되고..

감사합니다.

char *name = "KLDP";
char name[] = "KLDP" 는 차이가 있습니다.

char *name = "KLDP" 의 경우 KLDP 라는 문자열은 data 영역에 잡히고
name 은 bss 에 잡혀서 단순히 name 변수가 KLDP를 포인팅 합니다.

하지만 char name[] = "KLDP" 에서는, KLDP 라는 문자열은 data 영역에
잡히고 name은 bss에 잡히더라도, name이 "KLDP"를 포인팅 하는게
아니라, 중간에 name이 배열이므로, KLDP를 복사하는 루틴이 들어가게 됩니다. 그래서 첫번째 것의 값을 바꾸려고 하면, 에러가 나게 되지만, 두번째
것은 자신의 메모리를 가지고 있으므로, 그냥 값이 바꿔 집니다.

어셈블을 해보면, 복사 루틴이 있는 것을 볼 수 있습니다.




char name[] = "KLDP";

return name;

char *name = "KLDP"; 
return name;

전자는 함수가 종료하면 invalid 한 영역 - 즉 스택 -에 대한 포인터를 반환하지만
후자는 함수가 종료한 후에도 valid한 영역 - 데이터 섹션이 되었건 코드 섹션이 되었건 간에 - 에 대한 포인터를 반환합니다.

따라서 전자-스택에 잡힌 배열을 반환하는 방법-은 잘못된 방법이지만 후자-문자열상수-를 반환하는 것은 문제 없습니다.

다만 후자의 단점은 말그대로 문자열 상수만 반환가능하다는 것입니다. 즉 위의 예처럼 "KLDP" 같은 상수를 반환하는 경우라면 별 문제가 없지만, 만약 _snprintf등을 사용해서 런타임에 문자열을 합성해야 할 경우라면 위의 분들이 보여주신 것처럼 malloc을 통한 동적할당을 하던지 아니면 인자를 통해 복사받을 버퍼를 넘겨받던지, 아니면 static array를 사용해야겠지요. 각 방법의 장단점을 살펴보면
1. 복사받을 버퍼 및 버퍼크기를 인자로 넘겨받는다.
--> 사용하기도 구현하기도 귀찮다-_-; 하지만 가장 표준적/범용적이고 안전함
2. 동적할당
--> free를 잊지말고 해주어야 한다는 귀찮음보다는, 1번이라면 필요없을 "malloc"의 오버헤드가 덧붙여진다는 점이 가장 큰 단점임.
3. static array
--> 간편하지만 함수가 reentrant하지 않게 된다는 단점이 있음. 즉 서로 다른 쓰레드에서 접근한다거나 signal handler등에서 사용할 수 없음

__일반적으로__ 가장 추천할 방법은 역시 귀찮긴 해도 1번인 것 같습니다(june8th님의 코드 참조)




char name[] = "KLDP";

char *name = "KLDP";

두경우 모두 "KLDP"는 데이터 영역에 기록되나 char []의 경우 "KLDP"를 스택에 복사한 후, 그 위치를 포인팅한다. (char*는 data영역을 포인팅)

함수가 종료되면 당연히 char[]은 invalid한 영역이 된다.

'IT > C' 카테고리의 다른 글

malloc() 작동원리  (0) 2018.06.12
메모리 동적할당 realloc()  (0) 2018.06.06