안쓰니까 자꾸 헷갈려버리듯 하는 포인터 개념을 다시 정리해봅니다.
포인터도 함수에 매개변수로 넘겨줄 때 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] 는 컴파일 에러 발생! [] 가 *보다 우선순위가 높다.
}