2013. 4. 29. 16:41
다음의 내용은 Rushmo에서 포인터 교육 자료로 만든 내용입니다.
가져 가실때는 이 정보 남겨 주시는것이 예의 겠지요 ^^
아래 코드들은 각종 오류 상황에 대한 예시들이다.
1. 메모리 공간을 넘는 데이터의 대입
int i;
double *dp;
dp = (double *)&i;
*dp = 33.3;
e 형 변환을 통해서 포인터 주소 대입에는 문제없지만 , 실제로 데이터를 넣을 때 int 형식으로 선언된 4 바이트 공간에 8바이트의 데이터를 넣으면서 메모리가 깨지는 문제가 발생된다.
e 이때 주의할 것은 Debug 모드에서는 오류를 표시하지만 Release 시에는 해당 메모리가 깨진 것을 모르고 작동 되는 경우가 빈번하기 때문에 오류를 찾는데 많은 시간이 걸린다는 것이다.
2. 포인터 증가수식의 함정
int i;
int * p;
p = new int;
*p = 100;
printf("0x%08X \r\n", p );
i = (*p)++;
printf("i=%d , 0x%08X \r\n",i, p );
문득 생각하면 p에 들어 있는 값을 증가 시킨 뒤 그 값을 i에 넣기 때문에 i가 101이 출력 될 것 같지만 , 실제로는 100 이 출력된다.
그 이유는 ++ 연산이 뒤에 있기 때문에 i 변수에 100을 넣은 후 *p 값을 증가 시키기 때문에 *p는 101이 되어도 i는 100 이 그대로 있게 된다.
n 아래 코드의 경우는 더 혼동이 있을 수 있다.
i = *p++;
이 경우는 i에 *p값을 넣은 뒤 p의 주소를 증가 시키기 때문에 i는 100이 들어가고 , *p는 해당 메모리에 있는 예상하지 못했던 값이 들어 가고 , p 의 주소마저 변경되는 문제가 생긴다.
n 개인적으로는 이런 코드는 공동작업에서 실수를 발생시키는 원인이 되기 때문에 사용을 하지 않는 것이 좋다고 생각 한다.
3. Memory Overflow ( = Buffer Overflow , = Buffer Overrun )
아래의 코드를 보자.
void BufferOverflow(char * p)
{
char szBuffer[10];
strcpy(szBuffer,p);
printf("p=%s \r\n", p );
}
BufferOverflow("In computer security and programming, a buffer overflow, or buffer overrun, is an anomaly where a program, while writing data to a buffer, overruns the buffer's boundary and overwrites adjacent memory"); // 201 bytes
이 경우 szBuffer의 공간은 10바이트로 설정되어 있지만 , 복사하는 내용은 201 바이트가 된다.
strcpy 등의 함수는 목적지 버퍼의 공간을 체크하지 않고 p 로 넘어온 문자열에서 NULL 캐릭터가 나올때까지 반복으로 복사하는 기능을 하기 때문에 스택 메모리가 overflow되고 최종적으로 스택을 깨트리는 문제가 발생하게 된다.
n 관련된 내용은 아래에서 참고할 수 있다.
n 최근 버전의 Visual Studio에서는 strcpy_s 등의 보안성이 향상된 함수 사용을 권장한다.
댓글 없음:
댓글 쓰기