-----------------------------
우선 메모리에 관한 설명입니다.
C 프로그램을 실행시키면, 다음과 같이 4개의 영역으로 메모리가 나뉩니다.
+--------+ infinity
| stack |
| | |
| | |
| V |
: :
: :
: :
| ^ |
| | |
| | |
| heap |
+--------+
| global |
| data |
+--------+
|program|
| code |
+--------+ 0
(운영체제에 따라 모양이 조금 다른 경우도 있습니다. 예를 들면, Unix는 아마 stack이 program code 밑으로 내려가는 것으로 기억하고 있습니다.)
program code : 말 그대로 프로그램의 내용이 저장되는 곳입니다.
global data : global 변수들이 우선 이 곳에 저장이 됩니다. static으로 지정된 변수들도 이 곳에 함께 저장이 됩니다. 프로그램이 시작될때 모두 한꺼번에 미리 저장을 해 두죠.
heap: 이 곳이 프로그래머가 직접 사용이 가능한 메모리이며, malloc으로 메모리를 할당해줄 경우, 이 곳의 메모리를 씁니다.
stack: 컴파일러가 임시로 사용하는 곳입니다. 함수라던가를 부를 경우, 그 안에서 만들어지는 모든 local 변수들(malloc을 사용하지 않고 직접 정의된 경우)이 이 곳에 저장이 됩니다.
---------
char *c= (char*)malloc(sizeof(char)*10);
을 실행시키면, 10 바이트의 메모리를 heap에서 떼어다가 할당해준후, c가 그 장소를 가리키게 합니다.
여기서,
c = "hello!"
이렇게 하게 되면, 우선 프로그램은 "hello!"라는 문자열을 만듭니다. 이것은 어디까지나 함수내에서 만들어진 데이터 임으로 local 변수로 취급되어 stack에 저장이 됩니다. 그러고 나서 포인터 c가 hello!라는 이 변수를 가리키게 만듭니다. 앞에 malloc으로 만들어준 그 장소를 더이상 가리키지 않게 되죠.
여기서 이 c를 free를 시키려고 해도, c는 malloc으로 지정해준 메모리를 가리키고 있지 않고, stack에 있는 데이터는 프로그래머가 마음대로 제어할 수 없으므로 access 어쩌고 의 에러가 뜨는 겁니다.
그와 반대로
gets(c);
또는
c[0]='h'
c[1]='e'
는 malloc이 지정해준 장소에 문자열을 직접 입력해 넣는 방법이므로 문제가 없는 것입니다.
해결책
malloc 해준후
strcpy(c, "이게 복사될것");
free(c);
하면 된다. c의 주소값이 변하지 않고 복사 되기때문에...