안쓰니까 자꾸 헷갈려버리듯 하는 포인터 개념을 다시 정리해봅니다.
포인터도 함수에 매개변수로 넘겨줄 때 call by reference
, call by copy
의 원리를 적용받는다.
아래의 코드는 포인터를 부모함수에서 선언하고 서브프로그램에서 조작을 가할 때 자주 하는 실수다.
int main(void)
{
int num;
int *ptr;
foo(ptr); // call by value
for (int i = 0; i < 5; i++)
cout << ptr[i]; // segmentation fault
}
void foo(int *ptr)
{
ptr = (int *)malloc(sizeof(int) * 5);
for (int i = 0; i < 5; i++)
ptr[i] = i;
}
ptr은 주소값을 담는 변수다.
그 변수에다가 20바이트짜리 정수형 배열의 시작 주소를 넣어주었다.
문제는parameter passing
방식이call by value
였다는 것이다.
foo
의 ptr은 복사된 변수이다.
따라서 main의 ptr 변수의 값은 바뀌지 않는다.
따라서 call by reference
방식으로 넘겨주어야 main의 ptr값이 바뀔 것이다.
올바르게 수정된 코드
int main(void)
{
int num;
int *ptr;
foo(&ptr); // call by reference
for (int i = 0; i < 5; i++)
cout << ptr[i];
}
void foo(int **ptr)
{
*ptr = (int *)malloc(sizeof(int) * 5);
for (int i = 0; i < 5; i++)
(*ptr)[i] = i; // *ptr[i] 는 컴파일 에러 발생! [] 가 *보다 우선순위가 높다.
}