목차

Pointer guide; method and memory

🗓️

함수 내에서 포인터 변수 사용 요령

1. 선언부

  • 다음의 선언이 있다고 하자
char    *strcpy(char *dest, char *src)
  • char *strcpy 이 선언은 char형의 포인터, 즉 문자열로 반환하고 포인터 변수 destsrc를 매개변수로 받는 포인터 함수다.
  • char *dest의 정확한 표기법은 사실 char* dest다. 그래서 함수 내에서 다음 주소를 참조하기 위해 조작시 *dest++ 식으로 조작하면 안되고 dest++가 맞다.

2. 원래 주소의 보존

  • 이후 다음의 포인터 변수 선언과 할당이 있다고 하자.
char *tmp_dest;
tmp_dest = dest;
  • 이부분의 경우는 tmp_destdest가 같은 주소를 갖게 된다.
  • 이는 dest를 순회하기 위해서 dest의 시작 주소를 보존하는 것과 같다.
  • tmp_dest는 순회하면서 데이터를 조작하게 되면 dest반영된다.
  • dest의 데이터는 변경되지만 시작 주소는 보존된다. (반환 등에 유용하게 사용)

3. 순회 후 NULL값의 추가

  • 이후 다음의 코드가 또 있다고 보자
while(*src != '\0')
{
    *tmp_dest = *src;
    tmp_dest++;
    src++;
}
  • src의 값 *srcNULL이 올 때까지 순회하며 src의 문자열을 tmp_dest에 복사하는 strcpy의 핵심 로직이다.
  • 그런데 이렇게 돌게 되면 tmp_destNULL이 들어가지 않기 때문에 문자열의 끝을 알 수 없다.
  • 그래서 다음 코드를 while문 밖에 추가한다
*tmp_dest = '\0';
  • 그러면 완전한 복사가 완료된다.

메모리 영역 할당과 접근에 대한 간략한 정리

  • C에서 할당할 수 있는 메모리 영역 : stack 영역, heap 영역, read-only data영역
char dest[12];                             // stack
char *dest = malloc(sizeof(char) * 12);    // heap
char *dest = "            ";               // Read-only Data
  • dest[12] : 이 선언은 12개의 char형 공간을 미리 stack영역에 할당한다.
  • *dest = malloc(sizeof(char) * 12) : 이 선언은 12개 사이즈의 char형 공간을 미리 heap 영역에 할당한다.
  • *dest = "▫️▫️▫️▫️▫️▫️▫️▫️▫️▫️▫️▫️" : 이 선언은 Read-only Data 영역에 빈칸 12개의 문자열을 할당한다.

프로그램에서 read-only data 영역의 사이드 이팩트

  • 정해진 크기의 영역을 할당하는 것과 다르게 상수이므로 값 변경이 불가능하다. 변경 시도시 seg fault 발생.
    • 상수값의 개념은 알고 있었지만 C에서 위와 같이 선언하는 방식이 상수인 줄 몰랐음.
  • 값을 조작 (추가,삭제,변경)하고 싶다면 크기를 미리 할당하는 식으로 변수를 선언해야한다.
  • 프로그램 code영역과 밀접하므로 강제 조작시 버퍼 오버플로우 (버퍼 오버런)를 일으킬 수 있다.