|  |
| |
| BrokenPipe |
ptr변수는 어떤 변수의 주소값을 저장하는 변수고요
거기에 num의 주소값을 대입하고있습니다
ptr의 주소를 num의 주소와 같게했으니 num의 값이 나옵니다 |
2011/10/19 |
|
| hotchoco89 |
ptr의 주소를 num의 주소랑 같게 한게 아니고 ptr이 num을 가르키도록 주소를 준거 아닌가요 ??
ptr이랑 num의 주소는 각각 있는거잖아요? |
2011/10/19 |
|
| hotchoco89 |
그러니까 제 말은 실질적으로 ptr이 &num이고 *ptr이 num 인 거잖아요. 그러니까
int *ptr = num 하면 ptr에 &num이 들어가게 해야지 말이 되는게 아닌가 하는데 아닌가요? |
2011/10/19 |
|
| BrokenPipe |
포인터를 깊게 다루고 넘어가지 않은지라 소스코드만으로는 이해하기 힘들어서
어셈블리어로 봤는데요
사용한 소스입니다.
#include <stdio.h>
int main(){
int num=4;
int *ptr = #
return 0;
}
그리고 각각 $ebp-8(num) 과 $ebp-4(ptr) 의 값입니다.
(gdb) x/x $ebp-4
0xbffff764: 0xbffff760
(gdb) x/x $ebp-8
0xbffff760: 0x00000004
그.. 우선 int *ptr = # 이라고 하면
ptr변수에 num의 주소값이 들어가는게 맞습니다
ptr = num의 주소값
하지만 그 주소값은 int형의 범위(21억 ~ -21억)을 웬만하면 넘습니다.
(gdb) x/x $ebp-4
0xbffff764: 0x00000004
(gdb) x/x $ebp-8
0xbffff760: 0x00000004
이게 말씀하신 *ptr=num; 인데요
포인터로 선언한 변수는 일반 실수형이나 문자형으로 선언한것과는 다른형식의 데이터를 갖게되는것 같습니다.
실험을 제대로 해보진 않아서 모르겠지만
*ptr = num; 의 경우에서는
*ptr = 4;
ptr이라는 메모리를 담는 포인터변수에 4라는 메모리주소를 넣어서
ptr은 0x00000004의 정수값을 가지는게아닌
0x00000004의 메모리주소값을 가지는것같습니다.
이 부분에 대해서는 나중에 좀더 실험해 봐야겠네요 |
2011/10/19 |
|
| BrokenPipe |
지식이 얕아 ~같습니다의 추측을 사용한것에 대해서는 죄송합니다 |
2011/10/19 |
|
| BrokenPipe |
생각을 정리하고 쓴 댓글이 아니라서 다시 정리해보자면
포인터로 선언된 변수는 대입되는 값을 메모리주소로 간주하고
포인터에 접근할땐 그 포인터가 갖고있는 메모리주소에 접근합니다
#include <stdio.h>
int main(){
int num=4;
int *ptr = num;
printf(ptr);
return 0;
}
을 해보시면 printf함수의 인자에 0x00000004가 전달되어
세그먼트 폴트가 나는것을 보실 수 있습니다. |
2011/10/19 |
|
| hotchoco89 |
답변 감사합니다. 그러니까 제 말은 논리적으로 생각해보면 ptr이 num의 주소 &num을 의미하니까
포인트 변수를 선언할 때 int *ptr; 한 다음 ptr = # 하거나
int *ptr = num; 을 할 때 연결 되게 하는게 맞을 것 같은데
왜 int *ptr = #을 해야 되도록 만들었을까요 ?? |
2011/10/19 |
|
| BrokenPipe |
*ptr 자체는 메모리주소를 저장하기위한 포인터 변수이기 때문에
*ptr에 num의 메모리주소값을 넣기위해서는
*ptr = # 을 하는게 당연하다고 보는데요;;
말씀드렸다시피 많은 실험을 해본건 아니라서 확답은 못드리지만
int *ptr;
ptr=#
정상적으로 작동되는것 확인했고요
int *ptr = num; 은 말씀드렸다시피 num이 가지고 있는 4 라는 정수값이
ptr에 들어가게 되어 0x00000004라는 메모리주소를 가르켜서 안되는겁니다 |
2011/10/19 |
|
| Prox |
포인터 개념은 이해하셨으리라 생각되서, 포인터선언 질문만 답해드릴게요
int *ptr=#
위와 같이, ptr을 처음 사용할땐 포인터타입인걸 알려줘야 하므로 *ptr이라고 적어야만하고...
그후에 해당 변수(포인터타입 ptr)에 넣을 값(&num)을 적어주는게 맞습니다.
헷갈리신다면 이렇게 생각해보세요. 띄어쓰기만 바꿔서 쓰면 명확히 보일겁니다
int* ptr = # //포인터타입(int*) 선언과 동시에 대입 (ptr=&num)
int* ptr; //선언
ptr = # //주소대입 |
2011/10/20 |
|
| Prox |
참고로.. 선언에 사용되는 별표(예를들면 int *ptr=&num)는 type declaration의 의미를 갖고, 그 외에 사용되는 경우(예를들면 int a=*p 또는 *p=a)는 referencing의 의미를 갖습니다.
두 별표 모두 포인터와 관련되있지만 약간은 다른 용도로 쓰이죠 ^^ |
2011/10/20 |
|
| Prox |
위에있는 댓글도 잠깐 보자면요..
"int *ptr = num 하면 ptr에 &num이 들어가게 해야지 말이 되는게 아닌가" 라고 하셨는데..
ptr이라는 포인터변수를 우선 선언하고 (int* ptr;)
ptr 포인터변수에 num이라는 정수변수를 넣은 것이기 때문에 (ptr=num;) 타입에러가 됩니다.
int *ptr;
*ptr=num;
위와같이 적는다고 하더라도
*ptr=num; <- 이문장의 뜻이 "ptr이 가리키는 곳에 num의 값을 넣어라"라는 뜻이기 때문에
ptr변수에 num의 주소가 저장되는게 아니라, ptr변수가 가지고있는 주소에 num의 값을 write하려고 시도하게 됩니다.
(num의 주소는 어디에도 저장되지 않으며, ptr안에는 쓰레기값이 들어있으므로 *ptr=num할때 메모리write에 실패해서 프로그램이 crash될거에요) |
2011/10/20 |
|
| Prox |
글이 길어졌는데..... 요약하자면 ㅋㅋ
int *ptr=# 이문장은
int *ptr의 선언과 ptr=&num이 합쳐진거지..
int *ptr과 *ptr=&num이 합쳐진게 아닙니다~~
즉..... int *ptr=# 이문장에서 별표는 referencing이 아닌 type declaration의 의미를 갖는단거죠 |
2011/10/20 |
|
| BrokenPipe |
그래서 int* ptr; 이라고 웬만하면 다들 쓰시더라고요
int형포인터를 데이터형으로 하는 ptr 변수. |
2011/10/20 |
|
| hotchoco89 |
아 그렇군요
그런 깊은 뜻이..
답변 감사합니다. |
2011/10/26 |
|