함수 내에서 포인터 변수 사용 요령
1. 선언부
char *strcpy(char *dest, char *src)
char *strcpy
이 선언은 char
형의 포인터, 즉 문자열로 반환하고 포인터 변수 dest
와 src
를 매개변수로 받는 포인터 함수다.char *dest
의 정확한 표기법은 사실 char* dest
다. 그래서 함수 내에서 다음 주소를 참조하기 위해 조작시 *dest++
식으로 조작하면 안되고 dest++
가 맞다.
2. 원래 주소의 보존
- 이후 다음의 포인터 변수 선언과 할당이 있다고 하자.
char *tmp_dest;
tmp_dest = dest;
- 이부분의 경우는
tmp_dest
와 dest
가 같은 주소를 갖게 된다. - 이는
dest
를 순회하기 위해서 dest
의 시작 주소를 보존하는 것과 같다. tmp_dest
는 순회하면서 데이터를 조작하게 되면 dest
에 반영된다.dest
의 데이터는 변경되지만 시작 주소는 보존된다. (반환 등에 유용하게 사용)
3. 순회 후 NULL값의 추가
while(*src != '\0')
{
*tmp_dest = *src;
tmp_dest++;
src++;
}
src
의 값 *src
가 NULL
이 올 때까지 순회하며 src
의 문자열을 tmp_dest
에 복사하는 strcpy의 핵심 로직이다.- 그런데 이렇게 돌게 되면
tmp_dest
에 NULL
이 들어가지 않기 때문에 문자열의 끝을 알 수 없다. - 그래서 다음 코드를 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영역과 밀접하므로 강제 조작시 버퍼 오버플로우 (버퍼 오버런)를 일으킬 수 있다.