inflearn logo
강의

講義

知識共有

ホン・ジョンモのついていきながら学ぶC言語

9.17 ポインタ変数のサイズ

메모리의 '첫 번째 주소' 및 byte 단위 메모리 공간의 저장 순서에 대한 질문

解決済みの質問

646

kynoh

投稿した質問数 7

0

'9.17 포인터 변수의 크기' 강의를 보고, 의문이 생겨 질문 드립니다.  예를 들어, 다음과 같은 코드가 있습니다.
int a = 4;
float b = 4.0f;
double c = 5.0;

int *ptr_a = &a;
float *ptr_b = &b;
double *ptr_c = &c;

Q1. 포인터 변수(ptr_a)가 변수(a)에 대하여 저장하는 첫 번째 주소란, 그 변수(a)가 memory에 저장될 때, 가장 마지막에 저장되는 1 byte 메모리 공간의 주소를 의미하는 것이 맞나요?

Stack memory에 data가 저장될 때에는 High address로부터 Low address방향으로 저장된다고 알고 있습니다.

포인터는, 변수가 접근하는 메모리 공간의 첫 번째 주소를 저장하는데, 여기서 Memory를 살펴본 바, 첫 번째 주소란, 변수(a)가 stack에 저장될 때, 마지막으로 저장된 1 byte 메모리 공간으로 이해됩니다.

그리고가장 먼저 저장된 변수인 a의 주소는 bc보다 높은 주소에 위치하고,b의 주소는 c보다 높은 주소에 있습니다.

그렇다면, 변수(a)의 4 byte짜리 메모리 공간들에 대해서도 저장될 때, 가장 먼저 저장되는 메모리 공간은 나머지에 비해 높은 주소에 위치한다고 추론할 수 있습니다.

그러므로 포인터가 저장하고 있는 주소값, 즉 그 변수(a)의 첫 번째 주소란, 가장 마지막에 저장되는 1 byte 크기의 메모리 공간이라고 이해하고 있습니다.

 

Q2. x64에서 debugging을 실행할 때, 가장 나중에 저장되는 변수가 가장 높은 주소를 가지고 있는데, 왜 그렇습니까?

x86으로 실행했을 때와 마찬가지로, stack에 쌓이는 메모리 공간들의 주소는 from high to low이어야 한다고 알고 있습니다.

x64로 디버깅을 해보니, 먼저 저장되는 변수 자체의 메모리 공간이 저장되는 순서는 high to low 순으로 주소를 가지지만, 각 변수의 첫 번째 주소를 참고해보면, 이상한 점이 있습니다.


가장 마지막에 저장된 변수 c가 가장 높은 주소값을 가지고 있다는 것입니다.

stack에 저장되는 메모리들의 주소는 가장 높은 메모리 주소부터 낮은 메모리 주소의 방향으로 저장되는데, 여기서는 x86 환경에서 memory 확인했을 때와 달리 정반대입니다.

왜 그럴까요?

 

c

回答 2

2

kynoh

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의 주소는 bc보다 높은 주소에 위치하고,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에 위치하고 있다.)

 

 

1

honglab

안녕하세요? 지금 질문하신 내용들은 프로그래밍 언어의 범위를 넘어서 운영체제와 연관이 되는 부분입니다. 저도 운영체제나 컴파일러 전공자가 아니지만 궁금하신 내용과 관련있을 만한 내용들을 알려드리자면,

1. Endianness https://ko.wikipedia.org/wiki/%EC%97%94%EB%94%94%EC%96%B8

메모리에 데이터를 어떤 순서로 기록할지인데 우리의 직관과 다릅니다. 중간의 그림 보시면 쉽습니다. 강의 후반부에서 잠깐 다뤘던 것으로 기억합니다.

2. 스택

윈도우와 리눅스가 메모리 사용법이 다릅니다. 우리가 흔히 알고 있는 상식들은 리눅스 기준입니다. 그래서 강의 후반부에서는 리눅스에서도 주소를 보여드린 것으로 기억합니다.

도움이 되었기를 바랍니다.

0

kynoh

답변해주신 내용들 알아보니, 새롭게 만나게 되는 내용들도 많은 것 같습니다. 
나중에 C언어 강의 끝나고 복습하면서 다시 돌아봐야겠습니다.
답변 감사드립니다!  

Export template 안됨

1

28

2

완전히 똑같이 따라해도 exe파일이 안만들어져서 실행이 안됩니다.

1

56

3

main 함수에서 왜 int만 선언이 되는걸까요

1

57

2

8비트 2진수 변환시 왜 1을 더해야하나요?

1

55

2

혹시 강의를 빠르게 수강하려면 어디서부터 듣는게 좋을까요?

1

49

1

프로토타입과 함수간의 인자 불일치

1

73

2

12.12 헤더 관련 질문

1

60

2

Visual Studio Community 2026 사용 문의

1

138

2

Q. 15:30, 부호가 있는 8비트 정수 질문

1

61

2

getchar(), putchar()

1

94

3

강의자리ㅛ

1

80

2

비주얼스튜디오코드로 공부해도 상관없나요?

1

114

2

소스파일안에 여러 파일

1

76

2

F5와 F7의 차이

1

79

2

c = TWO * (a+b); 에서 a와 b는?

1

59

2

; 세미콜론을 붙이는 기준에 문의

1

70

1

Step over 기능 문의

1

53

2

2.6 강의 따옴표 출력 규칙 문의

1

76

2

int main 함수 관련 오류 문의

1

67

2

13.4 words[0]

0

61

2

11.7 함수를 구현해 봤습니다.

1

62

2

11.6 직접 strcmp와 strncmp를 구현해 보았습니다.

1

65

2

11.6 my_strcat과 my_strncat을 구현해봤습니다.

1

53

2

11.6 fit_str함수를 구현해 봤습니다.

1

54

2