char 배열
이 가득 찼을 때 메모리 상에서 무슨 일이 일어나는지
알고리즘 문제풀이를 하던 중 sscanf로 string에 들어온 정보를 쪼개서 char배열(A, B)에 저장하는데, 자꾸 첫 번째 배열(A)의 처음 문자에 NULL 문자(\0)가 들어왔다. 근데 배열 A만 받으면 잘만 들어온다. 그러다 문득 두 번째 배열(B)의 크기가 문자열의 길이와 일치할 때만 NULL 문자가 들어왔다는 사실을 알게 되는데 ...
모든 배열을 받아올 때 | 첫 번째 배열만 받아올 때 |
---|---|
🤔 요상하다..!
다시 보니 배열 B의 크기가 8이었음! frontend (최대 8글자) + NULL 문자 (1) = 최소 9 여야 했다.
문자열은 NULL 문자(
\0
)가 나올 때까지 문자열로 인식함
배열의 크기를 작게 설정한 건 알겠는데, 왜 앞 배열(A)에 영향을 주는지 궁금해서 실험해봄!
뭔가 자리가 부족해서 다른 배열 자리를 차지한 것 같은데.. 왜 다음 배열도 아니고 이전 배열인지?!
크기가 4인 배열 A, B를 선언하고, A배열엔 3개, B배열엔 5개를 넣어보았다.
char A[4], B[4];
A[0] = 'A';
A[1] = 'B';
A[2] = 'C';
B[0] = 'a';
B[1] = 'b';
B[2] = 'c';
B[3] = 'd';
B[4] = 'e';
printf("%s %s", A, B); // eBC abcdeBC
배열B의 크기가 초과되니까 먼저 선언된 배열A에 추가되는 모습!
이후 문자열 B는 널문자가 있는 A[3]이전까지가 된다.
char A[4], B[4], C[4];
// A 3개, B 5개, C 3개 문자 넣음
여전히 자신(B)의 직전에 선언된 배열(A)로 추가된다!
마찬가지로 자신(C)의 직전에 선언된 배열(B)로 추가된다.
널문자 나올 때까지 거슬러 올라가서 (C->B->A) 정의된다.
문자열 C | [C ] 1234 [B ] 5bcd [A ] eBC |
---|
이렇게 되는군... 2-1
번과 2-2
번의 합! 직전에 선언된 배열로 추가추가 ~
메모리 구조가 어떻길래 이렇게 되는지 궁금해서 배열의 주소값을 확인해 보았다. (이걸 제일 먼저 해봤어야..!)
배열의 주소값을 확인해 보았다
printf("%x %x %x", &A[0], &B[0], &C[0]);
// e57ad8cc e57ad8c8 e57ad8c4
A | B | C |
---|---|---|
e57ad8cc | e57ad8c8 | e57ad8c4 |
헐!!! C - B - A
순서로 차례대로 4byte씩(각 배열의 크기) 차이를 두고 있었다.
자리가 차면 먼저 선언된 배열로 굳이 이동해서 메모리를 빌려쓰는 게 아니라, 배열의 시작 주소부터 차례대로 값을 집어넣던 것 뿐이다. 그리고, 출력할 때는 널문자가 나올 때까지 차례대로 출력된 것 뿐
Stack 영역은 메모리의 가장 큰 주소값부터 거꾸로 할당 된다. Buffer overflow를 피하기 위해! (kernel의 영역이 변경될 여지를 줄이기 위해)
Memory View
에서 데이터가 들어오는 모습을 확인해 보았다. (초록색하이라이트 - 원래 배열C의 메모리 영역)
순서대로~ 차례차례~
일단은 A에게 할당된 공간(위 사진에서 초록색 하이라이트된 부분) 뒤에도 비어있었기 때문에 초과해서 넣은 문자 'E'가 메모리에 들어가긴 했다. 하지만 NULL 문자가 없기 때문에 A를 출력해보면 쓰레기값이 출력된다. (환경에 따라 오류가 발생할 수도)
잘 보고갑니다.
character array 는 왠만하면 쓰지 않는게 정신건강에 좋겠네요.
https://m-falcon.tistory.com/124