게시글
질문&답변
왜 출력값이 f가 나올까영...
'%f' 라고 쓰셔야합니다. 작성자 분은 f% 라고 쓰셨네요 :) (사진)
- 0
- 1
- 320
질문&답변
메모리의 '첫 번째 주소' 및 byte 단위 메모리 공간의 저장 순서에 대한 질문
2022. 06. 20. 혹시 다른 분들도 헷갈리시거나 그러실까봐 배운 것을 활용해서 자문자답해봅니다. :) Q1. 포인터 변수(ptr_a)가 변수(a)에 대하여 저장하는 첫 번째 주소란, 그 변수(a)가 memory에 저장될 때, 가장 마지막에 저장되는 1 byte 메모리 공간의 주소를 의미하는 것이 맞나요? 아니다. pointer가 저장하는 memory address는, 변수 a의 first address를 의미한다.그렇다면, a의 first address는 무엇일까? Little Endian인 x86 intel CPU architecture에서는 Low address에 있는 data가 Least Significant Byte에 저장된다. (bit-value 역시 least significant bit에서부터 저장된다.) 아래의 스크린 샷에서 a는 4 byte의 size를 가진다.그러므로, byte order를 나타내자면, [MSB] 00 00 00 04 [LSB]가 된다.little endian인 현재의 computer에서 data가 저장되는 순서는, low address에 있는 byte data가 먼저 저장되므로, 0x004ffbc0이 가리키는 memory space 04가 먼저 저장되었다. (사진) 그러므로 pointer ptr_a가 저장하는 a의 first address는 가장 먼저 저장된 공간을 의미한다. (사진) (질문 내용 중) 그리고가장 먼저 저장된 변수인 a의 주소는 b, c보다 높은 주소에 위치하고,b의 주소는 c보다 높은 주소에 있습니다. 그렇다면, 변수(a)의 4 byte짜리 메모리 공간들에 대해서도 저장될 때, 가장 먼저 저장되는 메모리 공간은 나머지에 비해 높은 주소에 위치한다고 추론할 수 있습니다. Data가 어떤 memory block에 저장될 때는 little endian방식으로 저장되었다. [MSB] 00 00 00 04 [LSB] '04'가 low address인 byte이므로 먼저 저장된 것이다. 그렇게 저장된 data object의 memory address는 Linux OS / GCC Compiler 기준으로 stack에 할당될 때, memory address가 high to low의 방향성을 가지게 된다. 즉 먼저 저장된 변수a가 나중에 저장된 포인터 변수 ptr_a보다, high address를 가진다는 것이다. 하지만 이 방향성이 변수 a에 대하여, 'high address에 있는 '00'이 먼저 저장된다'는 것을 의미하지는 않는다. Data를 저장하는 방식인 endianness와 memory layout에서 address의 방향성을 혼동하지 말자. Q2. x64에서 debugging을 실행할 때, 가장 나중에 저장되는 변수가 가장 높은 주소를 가지고 있는데, 왜 그렇습니까? (홍정모 교수님 말씀대로, OS / Compiler 에 따라 다르기 때문이다. Stack과 Heap에, data들이 memory를 할당받을 때, 그 address의 방향성이 다르다. 이 variable들은 모두 stack에 allocation된다.Linux OS / GCC 기준으로 from high to low address의 방향성에 따라 할당될 것이다.그렇다면, [High Address Memory]a, b, c, ptr_a, ptr_b, ptr_c[Low Address Memory] 인 방향성을 보일 것이다. Linux OS계열인 Ubuntu OS / Clang Compiler를 활용하는 Online compiler replit에서 확인해보자.) (사진) (먼저 stack에 저장된 a가 High Address에 위치하고 있다.나중에 저장된 ptr_c는 Low Address에 위치하고 있다.)
- 0
- 2
- 514
질문&답변
[(14. 구조체) - 9.구조체와 할당 메모리] - scanf()와 malloc()의 실행 순서에 따른 Heap Corruption Detected 오류
자문자답합니다! malloc()을 할 때, strlen()함수의 연산 결과값 때문에 scanf()함수를 먼저 사용해야 했던 거네요 ;; 무의식적으로 sizeof()처럼 생각한 실수였어요... 위의 source code처럼 scanf()를 malloc()보다 나중에 call하게되면, strlen(buffer + 1) 의 연산 결과값은 1 byte가 나오게 됩니다. _msize()함수로 할당된 메모리의 크기를 구해보면 1이 나오는 것을 확인할 수 있습니다. 그러고나서 scanf() 함수로 string을 입력받게되면, strcpy()를 call했을 때, 할당받은 메모리를 초과해서 string을 복사하게 됩니다. 즉 할당 받은 heap memory의 size를 초과하게 됩니다. 그러므로 free()로 해제했을 때, 문제가 발생하는 것이었네요. 반면에, scanf()로 먼저 string을 입력받으면, strlen(buffer + 1)는 입력받은 문자의 수 + \0 만큼의 size를 연산 결과값으로 내놓게 되고, 이 만큼의 size로 heap에 확보됩니다. 이 경우에 _msize()함수로 할당된 메모리의 크기를 구해보면, 입력된 문자수+1 만큼으로 나오게 됩니다. 그러므로 strcpy()를 call했을 때, 할당 받은 메모리의 크기만큼 정상적인 copy가 됩니다. 그러므로 free()함수를 call했을 때, 정상적으로 해제가 됩니다. 참고로 _msize() 함수는 VS에서만 제공되는 함수이고 표준이 아니라고 합니다! VS Code랑 online compiler에서는 왜 정상작동한건지.. 그건 사소한 의문으로 남아있네요.
- 0
- 1
- 1.2K