SW사관학교 정글7기 개발일지 (09/02)

c4fiber·2023년 9월 2일
0

SW사관학교 정글7기

목록 보기
20/49

gdb로 알아보는 포인터 교실

포인터란 대체 무엇일까?

포인터를 공부하다 보면 '무엇을 가르키는 변수' 라는 표현을 자주듣는다.

나는 이러한 표현을 좋아하지 않는데, 무엇을 가르킨다고 해서 특별한 취급을 받는것처럼 보이지만 실로는 그렇지 않다고 생각하기 때문이다.

어디까지나 특수한 목적을 위해 사용되는 '변수'일 뿐이지, 결국 '변수'라는 본질에서 벗어나지는 않는다고 생각한다.

따라서 이를 보여주기 위해서 간단한 프로그램을 작성하고 결과를 보이려고 한다.

디버깅 준비

사용한 소스코드

hello.c

#include <stdio.h>

int main() {
    char str[20] = "AAAAAAAAAAAAAAAA";
    int a = 10;
    int *p = &a;

    // 변수 a의 값 출력: 10
    printf("%d\n", a);

    // 변수 str의 값 출력: A x 16
    printf("%s\n", str);

    // 변수 p의 값(= 변수 a의 주소) 출력
    printf("p(0x%x)의 값: %x\n", &p, p);

    return 0;
}

해당 코드는 char배열, int, int *포인터 세가지의 변수를 선언하고 내용을 출력하는 코드이다.

컴파일에 사용한 명령어

gcc -g -m32 hello.c -fno-stack-protector -z execstack -o test

canary, ASLR을 해제해야만 분석이 용이하다. 추가로 -g 옵션을 통해 디버깅 정보를 바이너리에 삽입하도록 했다.

디버깅 시작

list 명령으로 소스코드를 확인하고 b 17 명령어를 사용해 17번째 'return 0' 코드에 브레이크 포인트를 설정했다.

r옵션으로 브레이크 포인트까지 진행했고 17번줄 'return 0' 코드가 실행되기 직전이다

포인터 p는 값 0xffffd1a8을 가지고 있고 0xffffd1a4주소를 사용하고 있다.
여기서 p가 가진 값은 사실 변수 a가 사용하는 공간(주소)의 값이다.

p에 저장된 값은 주소값이며, 이를 역참조하면 변수 a의 공간에 도달할 수 있다는 것이다.

결론

우리가 변수에 저장하는 값은 큰 의미를 두지 않지만, 포인터 변수에 저장하는 값은 '주소값' 이라면서 큰 의미를 부여하곤 한다.

하지만 둘 다 그저 임시로 저장한 '값'에 불과하며 포인터 변수에 저장하는 '값'은 실제 주소와 매칭되는 '값'일 뿐 특별하다고 별개로 생각할 문제는 아니라고 생각한다.

Dangling pointer

댕글링 포인터

유효하지 않은 메모리나 이미 할당이 해제된 주소를 가르키고 있을 경우 이렇게 부른다.

주로 free()를 진행한 포인터를 다시 접근하려고 시도할 경우 문제가 발생하는데

가끔가다가 free()를 진행한 포인터에 접근을 시도해도 되는 경우가 있다.

Sentinel Node

Sentinel: 감시자, 파수꾼

센티넬 노드는 어떠한 역할을 하는가? rbTree에서의 NIL, 트리나 연결리스트의 마지막을 의미하는 노드이다.

보통 linked list 혹은 binary search tree 등 트리형태의 구조를 사용할 경우
다음노드가 존재하지 않으면 NULL을 사용한다.

하지만 Sentinel Node를 NULL 대신에 사용하는 방법이 있다.
이경우 코드의 구현이 비교적 복잡해질 수 있지만 조금의 성능향상을 꾀할 수 있다.

  • 다음 노드에 접근하기 전에 해당 노드가 null인지 확인해야할 필요가 있고, 아니라면 접근 시도를 하겠지만
    Sentinel node는 접근자체는 가능하므로 계속 접근하면 된다.
  • Sentinel node를 활용할 때는 sentinel node의 값을 찾고싶은 값으로 세팅하고 탐색을 진행하기 때문에
    원하는 값을 찾았을 때 sentinel node인지, 아닌지만 확인하면 된다.

참고자료

profile
amazing idiot

1개의 댓글

comment-user-thumbnail
2023년 9월 2일

👍

답글 달기