c언어에서의 메모리 할당(malloc)와 포인터의 관계... 고수님들
글쓴이: ins878 / 작성시간: 수, 2004/09/01 - 5:02오후
안녕하세요~
다름이 아니라 학교에서 포인터와 메모리 할당에 관하여 토론을 하다가 이상한
것을 발견했는데, 너무나 이상해서 이렇게 글을 올립니다.
고수님들 한번 봐주세요.
###################################
소스 코드
###################################
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *p, *q;
p = (int *)malloc(sizeof(int));
*p = 15;
q = p;
free(p);
*q = 30;
printf("%d ",*p);
printf("%p ",&p);
printf("%p\n",p);
printf("%d ",*q);
printf("%p ",&q);
printf("%p\n",q);
return 0;
}
위 소스에서 포인터 p에 메모리를 할당(malloc)를 하고 바로 해제를 했습니다.
그리고는 포인터 p에 어떤 값이 들어있는가 봤더니, 이전에 메모리를 할당한 곳을 가리키더군요(q와 동일)
분명히~ 메모리를 해제하면 에러가 나거나, 쓰레기 값이 들어가야 하는데,
왜 q와 같은 같이 들어가는가요?
고수님들 궁금해 미치겠습니다.
위 소스 코드에 대해서 자세히 가르쳐 주세요~~ T.T
Forums:
Re: OS 에 따라서;;
OS 에 따라서 문제없이 돌아갈 수도 있습니다.
같은 OS 라도 경우에 따라서 문제없이 돌아갈 수도 있죠.
원칙적으로는 *q 에 값을 대입하는 부분에서 프로그램이 죽어야 겠지만,
OS 에 따라서 틀리게 동작하게 됩니다. OS 의 메모리 사용 방식에 따른 차이죠.
P.S.) 하지만, 명백히 잘못된 코드입니다.
돌아간다고 해서 옳은, 혹은 써도 되는 코드인건 아니죠.
수정) 한가지 답변을 빼 먹었군요.
malloc() 한 메모리 영역을 free() 한다고 해서 그 영역을 가리키는 포인터 값이
초기화 되는것은 아닙니다.
malloc() 로 할당된 영역과, 그 영역의 주소를 가지는 포인터 변수와는 관련성이 없죠.
그리고, free() 한 메모리 영역의 값 역시나 변하지 않습니다.
그것은 garbage 값이라는게 어째서 존재하는지를 생각해 보시면 답을 얻으실 것이라고 생각합니다.
포인터를 번지라고 해보죠.. 특정 집을 가르키는 번지q,p 번지.
포인터를 번지라고 해보죠.. 특정 집을 가르키는 번지
q,p 번지.. 선언 ( 빈공간을 가르키는 번지죠 )
p번지에 공간을 할당해줍니다..
그리고 p번지의 공간안에 15란 값을 넣습니다..
q 번지의 내용에 p 번지의 내용을 넣습니다..
p 번지의 공간을 해제 합니다 ( p 번지가 사라지는건 아닙니다 )
q 번지의 공간에 30을 넣습니다.. <-- 오류입니다. 공간은 해제됬으니까..
현재 q 와 p는 같은 번지이다..
그러니 같은 내용이 찍히지요..
오류가 안났다고 해서 정상코드가 아닙니다.. 메모리의 상황에
따라서 세그폴트가 날수도 있는 코드입니다..
포인터도 엄연히 4바이트로 된 메모리 공간입니다.
메모리 할당된 공간과는 별개죠 ( 포인터 ) 가르킴..-> ( 공간 ) 입니다..
Re: c언어에서의 메모리 할당(malloc)와 포인터의 관계... 고수?
전 고수는 아니지만 malloc 은 heap 영역을 할당해주는걸로 알고 있습니다.
메모리를 해제한다는건 "할당받았던 그영역을 os가 사용하도록" 하는것입니다.
만약에 다시 malloc 을 하거나 다른 프로세서에서 malloc (혹은 비슷한) 을 한다면 그영역을 사용할수도 있습니다.
메모리의 데이터가 해제했다고 쓰레기 값이 들어가진 않습니다.
위코드가 실행되는 시간동안 다른 프로세서가 그 영역을 사용하게 된다면 또 다른 값이 찍힐수도 있습니다.
틀린곳이 있다면, 고수님들 지적바랍니다.
ps. 코드는 bbcode를 이용하심이.. :D
언제나 시작
Re: c언어에서의 메모리 할당(malloc)와 포인터의 관계... 고수?
프로세스간에는 주소공간이 다르지 않나요? :)
free() 이후에 초기화 않된 포인터로 잘못된 참조를 막기위해
보통 이런 메크로를 씁니다.
#define SAFE_FREE(p) { if(p) { free((p)); (p)=NULL; } }
-----------
청하가 제안하는 소프트웨어 엔지니어로써 재미있게 사는 법
http://sozu.tistory.com
고수님들~ 정말로 감사드립니다.
늘 여기만 오면, 저의 궁금증이 모두 풀려서 좋습니다.^^
고수님들~ 정말로, 정말로 감사드립니다.
Re: c언어에서의 메모리 할당(malloc)와 포인터의 관계... 고수?
전 heap 영역을 말하는건데요?
프로세서별로 할당받을수 있는 heap 영역도 정해져있나요? (잘몰라서.. :D )
궁금합니다.
보통 저도 사용하고 있습니다. :)
언제나 시작
Re: c언어에서의 메모리 할당(malloc)와 포인터의 관계... 고수?
참고로 말씀드리면
몇몇 분이 말씀하신 대상체가 저장되는 공간이 스택 영역이니 힙 영역이니 하는 문제는 사실 C가 상관할 바가 아닙니다. C에는 대상체의 속성과 관련하여 3가지의 기억부류를 가지고 있을 따름입니다.
大逆戰
Re: c언어에서의 메모리 할당(malloc)와 포인터의 관계... 고수?
코딩하는 사람이 상관할바겠죠. :)
언제나 시작
Re: c언어에서의 메모리 할당(malloc)와 포인터의 관계... 고수?
코딩하는 사람도 먼저 storage에 대한 이해를 하는게 바릅니다.
- 죠커's blog / HanIRC:#CN
..
조금 다른 예를 들어보자면
int p[2]; 과 같이 정의해놓고
p[0]= 0;
p[1]=1;
p[2]=2;
p[3]=3;
이렇게 사용한다면..아주 짧은 프로그램에서는 에러가 나지 않을수도 있습니다.
그렇다고 해서..오 잘되네~ --; 이런 생각을 가지시는 분은 없겠죠.
p[2],p[3]의 영역은 보장되는 영역이 아니므로
프로그램이 조금만 길어진다해도..충돌이 일어나겠죠..
메모리 영역은 다르지만..비슷한 경우라고 생각됩니다.
Re: c언어에서의 메모리 할당(malloc)와 포인터의 관계... 고수?
Heap 이던 Stack 이던 상관없습니다.
User Process 는 독립적인 Process Address Space 를 가지고 있습니다. :)
-----------
청하가 제안하는 소프트웨어 엔지니어로써 재미있게 사는 법
http://sozu.tistory.com
Re: c언어에서의 메모리 할당(malloc)와 포인터의 관계... 고수?
아.. 제가 이해를 잘못했나요? 인용하셨길레 제가 말한 뜻하고 틀린것 같아서 한참을 읽었습니다.
GunSmoke님 말씀이
그래서, 저는 당연히 storage에 저장되는건 코딩하는 사람이 이해를 하고 있어야 된다는 생각에 적은 말입니다.
-_-;; 뭔가 의사소통에 문제가.. 제가 잘못 이해했다면 용서해주시구요, 틀렸다면 쪼금만 더 지적해주세요
언제나 시작
Re: c언어에서의 메모리 할당(malloc)와 포인터의 관계... 고수?
아.. 감사합니다. 제가 잘못알고 있었군요. :)
언제나 시작
Re: c언어에서의 메모리 할당(malloc)와 포인터의 관계... 고수?
C에서 말하는 storage는 다분히 추상적인 개념입니다. 이를 구현할 때
스택이니 힙이니 하는 용어가 등장하는 거죠. 한 마디로 이 둘은 전혀
다른 차원의 용어라는 뜻입니다. 그리고 OP의 질문에 대해서는 C 언어의
차원에서 답변해도 충분하다는 뜻입니다.
그리고 일반적으로는 C 언어의 추상적인 관점에서 프로그래밍 하는 것이
이식성 측면에서 바람직합니다. 이식성을 희생하고 성능을 극도로 추구해야
할 상황이 아니라면요.
[quote="alwaysN00b"][quote="sozu"]Heap
모든 프로세스가 각각 독립적인 Process Address Space를 가지고 있다는 것은 맞지만, 그게 alwaysN00b 님이 말씀하신 것을 반박하지는 못합니다. 프로세스 A의 주소 100 이 가르키는 값이 프로세스 B의 주소 100이 가르키는 값과 서로 다르다는 것이, 두 프로세스가 완벽하게 구분된 Physical 메모리를 사용한다는 것을 의미하지는 않으니까요.
가령, VirtualAlloc 등으로 메모리를 할당하고, 그것을 Free했을 경우, 해당 Physical 메모리는 다른 프로세스가 사용할 수 있습니다.(서로 주소값은 다르겠지만요. 뭐 이때 VirtualFree를 호출하고 다시 억세스하려고 하면 Access Violation이 나긴 하겠군요.;; ) Heap의 경우도 마찬가지입니다. 다만 Default Heap은 프로세스마다 고유하게 만들어지며, 컴파일 옵션(링커의 옵션이었던가요. 기억이 잘.-ㅅ-; )으로 사이즈가 조절이 됩니다. 구현은 플랫폼마다 달라질 수도 있겠습니다만(제가 Win32외엔 잘 몰라서요.;; ) 대동소이할거라고 생각됩니다.
^^
다시 읽어보니 제가 주제를 벗어난 답변을 했군요. 지적 감사합니다. :)
-----------
청하가 제안하는 소프트웨어 엔지니어로써 재미있게 사는 법
http://sozu.tistory.com
Re: c언어에서의 메모리 할당(malloc)와 포인터의 관계... 고수?
아.. 죄송합니다. 제가 무지하여 잘 이해가 되질 않습니다.
질문자의 의도에 필요한 답이 올라왔다고 생각합니다.
언제나 시작
댓글 달기