[질문]C언어에서 포인터 질문입니다...
글쓴이: OpenSnake / 작성시간: 목, 2007/09/20 - 5:50오후
#include <stdio.h> int main() { int a=1; int *ap; *ap = a; printf("%d\n",&ap); printf("%d\n",*ap); printf("%d\n",ap); return 0; }
이 코드 말이죠...리눅스에서는 아무런 오류가 안나옵니다..
근데 윈도우 Visual C++6 에서 실행하면 오류뜨면서 종료가 되던데
왜 리눅스에서는 아무런 문제가 없는데
윈도우에서는 문제가 있는거죠??
Forums:
오류가 안나면
오류가 안나면 그거야말로 큰일인데.. -_-;
*ap = a; --> ap = &a;
*ap = a; --> ap = &a; 빼고는 문제 없는거 같은데요?
여러가지 문제가
여러가지 문제가 있스빈다~
*ap = a;
컴퓨터가 자폭해도 할말이 없는 코드입니다. 초기화 되지 않은 포인터 변수에 쓰기를 시도하지 마세요.
printf("%d\n",&ap);
int **의 크기가 int형과 같지 않다면 문제가 생길 수 있습니다. 가변 인자 함수에서는 매개변수의 타입에 대해서 주도면밀하게 신경을 써야 합니다.
printf("%d\n",ap);
int *과 int형의 크기 또한 다를 수가 있습니다. 포인터가 64비트고 int형이 32비트라면? 역시 컴퓨터가 자폭을 해도 할말이 없습니다.
리눅스에서 아무
리눅스에서 아무 옵션없이 컴파일하면 에러없이 컴파일되지요.
하지만 컴파일된 코드를 실행하면 seg fault 납니다.
리눅스에서 에러가 안난다는 말은 좀 이상하군요.
디스어셈블 해보면
(gdb) disas main
생략
0x08048385 : movl $0x1,0xfffffff8(%ebp) <== int a=1;
0x0804838c : mov 0xfffffff4(%ebp),%edx
0x0804838f : mov 0xfffffff8(%ebp),%eax
0x08048392 : mov %eax,(%edx) <== *ap = a;
우선 ap 포인터에 초기 값이 아직 주어지지 않았기 때문에
이 ap 포인터엔 스택상의 임의의 쓰레기값이 들어가 있게 됩니다.
봅시다.
(gdb) b *0x0804838f
Breakpoint 1 at 0x804838f
(gdb) r
Breakpoint 1, 0x0804838f in main ()
(gdb) i r eax edx
eax 0x1 1
edx 0x8048409 134513673
(gdb) x/16x 0xbfdf0d40
0xbfdf0d40: 0xb7f3d8b9 0x0804958c 0xbfdf0d58 0x080482a4
0xbfdf0d50: 0xb7f78ff4 0x0804958c 0xbfdf0d78 0x08048409 <== ap포인터.
0xbfdf0d60: 0x00000001 0xbfdf0d80 0xbfdf0dd8 0xb7e49050 보시는대로 임의의
0xbfdf0d70: 0xb7fbcce0 0x080483f0 0xbfdf0dd8 0xb7e49050 값이 들어가 있습니다.
*ap = a; 란 코드는 이 0x8048409 위치에 값 1을 써 넣으려
하는거죠. 0x8048409 위치는 사실 libc코드의 일부로
거기에 값을 써 넣으려는 시도는 segfault를 내개됩니다.
(gdb) x/x 0x8048409
0x8048409 <__libc_csu_init+25>: 0xff18bb8d
(gdb) x/i 0x8048409
0x8048409 <__libc_csu_init+25>: lea 0xffffff18(%ebx),%edi
만약 이 *ap포인터 위치에 우리가 값을 써 넣을수 있는 어떤 주소가
있었다면 심지어는 실행시 segfault 조차 안나게 되고
에러 디버깅은 더 어렵게 될수도 있지요.
(gdb) c
Continuing.
Program received signal SIGSEGV, Segmentation fault.
0x08048392 in main ()
(gdb) bt
#0 0x08048392 in main ()
(gdb) i r eax edx
eax 0x1 1
edx 0x8048409 134513673
..
댓글 달기