돌고돌아 포인터

포인터 기본 개념

int x = 42; // x는 값 42를 저장
int* ptr = &x; // // ptr은 x의 주소를 저장
printf("%d", *ptr); // *ptr로 x의 값(42)에 접근

포인터 사용 이유

8byte와 타입의 관계

char        // 1바이트
int         // 4바이트  
char*       // 8바이트 (포인터는 주소를 저장)
char**      // 8바이트 (포인터의 주소를 저장)
char***     // 8바이트 (포인터의 포인터의 주소를 저장)

8바이트인 이유

각 단계별 포인터 연산 분석

Step2 : 문자열 복사

char* argv_addresses[argc];  // 문자열 주소들을 저장할 배열
for(int i = argc - 1; i >= 0; i--) {
    size_t arg_len = strlen(argv[i]) + 1;
    stack_ptr -= arg_len;           // 스택 포인터를 문자열 크기만큼 이동
    memcpy(stack_ptr, argv[i], arg_len);  // 문자열 복사
    argv_addresses[i] = stack_ptr;  // 복사된 문자열의 주소 저장
}

Step4 : NULL 포인터 추가

stack_ptr -= sizeof(char*);    // 8바이트만큼 공간 확보
*(char**)stack_ptr = NULL;     // NULL 포인터 저장

Step5 : argv 포인터들 저장

for(int i = 0; i < argc; i++) {
    stack_ptr -= sizeof(char *);           // 8바이트 공간 확보
    *(char **)stack_ptr = argv_addresses[i]; // 문자열 주소 저장
}