ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 배열의 이해
    C언어 2020. 3. 5. 19:54

    수정 필요

     

     

    이번 포스트에서는 한가지 재미있는 주제에 대해서 다룰것이다.

    바로 char ch[10] = { "Hello" } 와 같이 문자(배)열을 선언과 동시에 "Hello" 라는 문자열 상수로 초기화 하였을 때 내부적으로 어떤 과정을 통해서 문자 배열 ch에 "Hello" 라는 문자열 상수가 들어가는지에 대해서 다룰 것이다. 

    위의 내용을 다루기 앞서 자료형의 개념에 대해서 다시 짚고 넘어가면 다음과 같다. 자료형은 일정 길이의 메모리에 있는 자료 또는 정보를 해석하는 방법이라고 하였다. 즉 메모리에 61 이라는 값이 있다고 하면 이 값을 int 로 해석하면 부호있는 10진 정수 61이 되는 것이고 반대로 char로 해석하면 61이라는 값은 'a' 라는 문자로 해석이 될 수 도 있다는 의미이다. 

    위와 같이 char 배열 ls의 크기를 12byte 만큼 선언하고 문자열 상수 "i(공백)am(공백)a(공백)boy" 다음과 같이 초기화 하였을 때 해당 배열의 주소에 메모리를 확인해보면 다음과 같다.

    위와 같이 메모리의 1byte 단위로 12byte 크기 만큼의 메모리가 초기화 되었으며 해당 메모리 안에는 값이

    69 20 61 6d 20 61 20 62 6f 79 00 00 이라는 값이 들어가 있는 것을 확인 할 수 있다. 이 각각의 값을 무엇으로 해석 할 것인가? 라고 했을 때 위에서 char 자료형으로 명시함으로 써 각각의 값을 문자로 해석하기로 지정하였다. 따라서 메모리에 있는 값은 char 자료형으로 해석 되어 다음과 같이 해석된다.

    69 => ' i ' ,  20 => 공백,    61 => ' a ' ,     6d => ' m ' ....... 이러한 방식으로 계속해서 해석 된다.

    위의 내용을 통해 자료형의 역할에 대해서는 이제 확실히 이해했을 것이다. 그렇다면 ls 배열에 "i am a boy"와 같이 문자열 상수로 초기화를 하면 어떤일이 일어날 것인가 ? 라는 의문에 대해 어셈블리어를 통해 어떠한 일들이 일어나는지 알아보자

    위의 자료는 디버깅을 통해 기계어 수준에서 어떤 일이 일어나는지 확인 할 수 있도록 해주는 자료이다. 

    현재 ls 배열의 주소에 메모리를 보면 cc 라는 쓰레기 값이 들어있는 것을 볼 수 있다. 이제부터 하나씩 실행시키면서 어떤 일이 발생하는지 확인해 보자

    위와 같은 어셈블리 명령이 내려졌을 때 69 20 61 6d 라는 값이 ls 배열의 주소에 해당하는 메모리에 들어가는 것을 볼 수 있다. 이는 위에서 설명한 경우 1에 해당하는 과정을 통해 ls 배열의 주소에 해당하는 메모리에 문자열 상수 " i am " 라는 값이 들어간다는 것을 볼 수 있다. 

    추가적으로 해당 어셈블리 명령이 내려질때 위쪽 명령은 어떤 주소의 메모리에서 값을 꺼내오라는 의미이며 아래쪽 명령은 어떤 주소의 메모리에 꺼내온 값을 넣으라는 명령과 같다. 그렇다면 한번 위쪽 명령이 가리키는 메모리의 주소로 가보자

    위와 같이 어셈블리명령에서 X라는 주소의 메모리에 있는 값을 가져오라는 명령에 따라 해당 주소의 메모리를 매핑하여 보면 쉽게 이해가 된다.

    " i am a boy " 라는 문자열 상수는 가상메모리의 영역  포스트에서 설명했던 data 영역이라는 메모리에 저장이 되었으며 해당 data 영역의 메모리에 저장 된 상수를 불러와서 [ls] 라는 배열이 있는 메모리에 해당 상수를 넣으라는 명령이 이루어 진 것이다.

    쉽게 생각하면 int i = 0; 즉 i 변수에 해당하는 메모리에 0이라는 값을 단순 대입 하듯 ls 라는 배열의 메모리에 data 영역의 메모리에 저장 된 상수의 일부인 69 20 61 6d 라는 값을 대입하여 해당 값을 char 형으로 해석한다고 볼 수 있다. 나머지 과정을 살펴보자

    위와 같이 다음 명령을 통해 20 61 20 62 라는 값이 ls 배열의 메모리에 추가적으로 대입되었다. 위와 같은 과정을 통해 총 위에서 보여준 자료의 파란색 박스의 섹션마다 ls 배열의 메모리에 값이 추가되며 해당 배열이 사용자가 초기화 한 문자열 상수로 채워진 것을 알 수 있다.

     

    즉 요약하자면 다음과 같다.

    int i = 20 ; => 20 이라는 변수를 i 라는 인스턴스에 대입하며 해당 상수 값은 int 형으로 해석

    char ls[12] = > 연속 된 char 인스턴스 들을 생성하며 해당 인스턴스의 수는 12개

    ls [ 12 ] = " i am a boy " => ls 배열의 기준 주소 인스턴스에 상수 69라는 값을 대입, ls 배열의 기준 주소로 부터 1칸 떨어진 인스턴스에 상수 20라는 값을 대입 .... 해당 과정이 계속 이루어짐 또한 해당 상수의 값을 char 형으로 해석한다. 이 모든 과정에서 이루어 지는 상수들은 배열을 초기화 선언시 기술한 문자열 상수 " i am a boy "가 data 영역의 메모리에 저장되며 해당 메모리에 있는 상수를 불러와서 ls 배열의 각 인스턴스 요소에 상수를 집어 넣는 것이다. 

     

    이러한 과정을 뜯어서 이해하는 것은 본질적인 이해에 큰 도움이 될 것이다.

    'C언어' 카테고리의 다른 글

    스택 프레임 & 재귀함수  (0) 2020.03.13
    포인터의 이해  (0) 2020.03.07
    메모리 복사  (0) 2020.03.05
    메모리 동적 할당 및 해제  (0) 2020.03.04
    가상메모리  (0) 2020.03.03

    댓글

Designed by Tistory.