Post

C Language: 동적할당(Dynamic Allocation), 구조체(Structure), typedef, 열거형(enum)

C Language: 동적할당(Dynamic Allocation), 구조체(Structure), typedef, 열거형(enum)
  • 8-1 힙 메모리(Heap Memory)

    • 메모리 레이아웃(Memory Layout): 컴퓨터 운영체제에서 메모리의 관리, 할당을 위해 가상으로 나누어놓은 메모리 공간
      • 스택 메모리(Stack Memory)
        • 컴파일 시점에 고정되는 지역변수(배열등)을 저장
        • 할당과 해제의 속도가 상수시간(O(1))로 빠름
        • 컴파일 이후 변경 불가능
        • 저장되는 정보들의 수명이 프로그램 수명과 같음.(불필요한 메모리 점유 가능)
      • 힙 메모리(Heap Memory)
        • 동적으로 할당과 해제 가능한 영역
        • 스택 메모리에 비해 할당과 해제가 느린편 (운영체제 개입, 메모리 탐색 등)
      • 코드 섹션(Code Section): 소스코드들의 빌드 결과물들이 저장
      • 데이터 색션(Data Section): 전역변수, 정적변수등 데이터가 저장
  • 8-2 동적할당(Dynamic Allocation)

    • 프로그래머가 임의로 메모리 공간을 사용하겠다 선언하여 변수에 지정하는 방식
      • 메모리 할당(대여) (Memory Allocation)
        • 힙 메모리 관리자에게 필요한만큼 메모리를 요청
        • 해당 크기만큼 연속된 메모리 위치의 주소를 찾아서 반환
      • 메모리 사용 (Memory Use)
        • 필요한 작업 수행 가능
        • 메모리에 기본으로 들어있는 값은 무작위 값(이전에 메모리에 쓰였던 값 등등)
          • 보안 영역으로 들어갈 경우 데이터 유출 가능
      • 메모리 해제(Memory deallocation, Memory delete)
        • 사용이 끝난 후, 메모리 할당 해제를 요청
        • 메모리 위치를 점유되지 않은 상태로 바꿈
    • 프로그램에 의한 자동 할당 해제가 되지 않기 때문에 해제하지 않으면 사용가능한 공간이 계속 줄어드는 메모리 누수(Memory Leak)가 생김
    • 사용 함수
      • malloc() (Memory Allocate)
        • 필요한 공간만큼 메모리를 할당
          • 어떤 자료형을 할당할 지 모르기에 void*로 주소를 반환, 필요한 형태로 변환해줘야함.
            1
            2
            3
            4
            
              int* Num;
              Num = (int*)malloc(sizeof(int) * 10); //10개 짜리 int 배열
              Num[9] = 12;
              printf("%d", Num[9]); //12 출력
            
      • calloc() (Clear and Memory Allocate)
        • malloc()과 동일한 기능이나, 할당되는 공간의 값을 0으로 모두 초기화시켜 랜덤한 쓰래기 값으로 차있는 것을 방지.
          1
          2
          3
          4
          
            int* Num;
            Num = (int*)calloc(10, sizeof(int)); //10개 짜리 int 배열
            Num[9] = 12;
            printf("%d", Num[9]); //12 출력
          
      • realloc() (Re-Allocate)
        • 이미 할당된 메모리를 다른 사이즈로 재할당하는 함수.
          1
          2
          3
          4
          5
          6
          7
          
            int* Num;
            Num = (int*)calloc(10, sizeof(int)); //10개 짜리 int 배열
            Num[9] = 12;
            printf("%d", Num[9]); //12 출력
            realloc(Num, sizeof(int) * 14)// 14개 배열로 재할당
            Num[13] = -9;
            printf("%d", Num[13]); //-9 출력
          
      • free()
        • 할당된 메모리를 해제해 사용 가능한 메모리로 되돌림
      • memset()
        • 메모리를 특정한 값으로 초기화
      • memcpy()
        • 다른 메모리의 내용을 복사해옴
      • memcmp()
        • 2개의 다른 메모리 값을 비교
  • 9-1 구조체 (Structure)

    • 여러 자료형을 묶어 새로운 자료형으로 사용할 수 있게 해주는 기능 ```c struct Car { int Wheels; char Color; int Year; }; //세미콜론 필요

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      
        int main(){
            struct Car Truck;
            Truck.Wheels = 4;
            Truck.Color = 'W';
            Truck.Year = 2016;
            printf("%d", Truck.Year); //2016 출력
        }
        ```   * 함수의 반환형, 매개변수형으로 사용하여 여러 값을 한번에 전달 가능
        ```c
        struct Car
        {
            int Wheels;
            char Color;
            int Year;
        };	//세미콜론 필요
        void printInfo(struct Car tempCar){
        printf("%d %c %d", tempCar.Wheels, tempCar.Color, tempCar.Year);
        }
        int main(){
            struct Car Truck;
            Truck.Wheels = 4;
            Truck.Color = 'W';
            Truck.Year = 2016;
            printInfo(Truck); //4 W 2016 출력
        }
        ```
      
  • 9-2 Typedef

    • 기존 선언된 자료형을 새로운 이름으로 다른 이름을 추가
      • ex) site_t => typedef unsigned long long size_t
      • 구조체의 경우 불필요하게 struct 키워드를 반복해서 쓰지 않아도 됨
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        
          typedef struct
          {
              int Wheels;
              char Color;
              int Year;
          }Car_t;	//세미콜론 필요
        			
          int main(){
              Car_t Truck = {0,};	//struct 없이 선언
              printf("%d", Truck.Year); //0 출력
          }
        
      • . 과 -> 둘다 접근에 사용 가능
      • 일반적인 자료형처럼
        • 함수 반환형과 매개변수형에 사용 가능
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          
            struct Car
            {
                int Wheels;
                char Color;
                int Year;
            };	//세미콜론 필요
            void printInfo(struct Car tempCar){
            printf("%d %c %d", tempCar.Wheels, tempCar.Color, tempCar.Year);
            }
            int main(){
                struct Car Truck = {0,};
                printInfo(Truck); //0 0 출력
            }
          
        • 포인터 사용 가능
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          
            typedef struct
            {
                int Wheels;
                char Color;
                int Year;
            }Car_t;	//세미콜론 필요
            void printInfo(Car_t tempCar){
            printf("%d %c %d", tempCar.Wheels, tempCar.Color, tempCar.Year);
            }
            void changeYear(Car_t* tempCar){
                ++(*tempCar).Year;
            }
            int main(){
                Car_t Truck = {4,'W', 2016};
                Car_t* targetPointer = &Truck;
                changeYear(targetPointer );
                printInfo(Truck); //4 W 2017 출력
            }
          
        • 배열 사용 가능

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          
            typedef struct
            {
                int Wheels;
                char Color;
                int Year;
            }Car_t;
            void printInfo(Car_t tempCar){
            printf("%d %c %d", tempCar.Wheels, tempCar.Color, tempCar.Year);
            }
            int main(){
          					
                Car_t Trucks[2] = {{4,'W', 2016},{6,'Y', 2012}};
          					
                printInfo(Trucks[1]); //6 Y 2012 출력
            }
          
  • 9-3 구조체와 클래스

    • 객체 지향 프로그래밍(Object Oriented Programming)의 class 개념과 유사 * 필요한 여러 자료나 개념을 하나의 객체로 묶어서 사용. * OOP class의 상속(Inheritance), 접근 제한 지정자(public, private, protected)등 차이점 탓에 완벽히 같은 개념은 아님. * 클래스에선 맴버 변수를 선언 가능하지만, C언어 구조체는 절차 지향 언어로서 문법상에 기능이 없음

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      
        typedef struct
        {
            int Wheels;
            char Color;
            int Year;
            void printInfo(){	//맴버 변수 불가능! 오류!
                printf("%d %c %d", Wheels, Color, Year);
            }
        }Car_t;
        int main(){
            Car_t Trucks[2] = {{4,'W', 2016},{6,'Y', 2012}};
            Trucks[1].printInfo(); 
        }
      
  • 9-4 enum (열거형, Enumeration)

    • 특정한 값을 다른 이름으로 재선언
      • 단순 값이 아닌 이름 표현을 통한 가독성 증가
      • const같은 수정 방지 효과
      • c++에서 기본 문법상으로 enum 이름에 바로 접근할 수 없어 다음 방법등을 사용
        • switch문을 통한 문자열 반환
        • 배열 맵핑
        • magic_enum 라이브러리 사용 (C++ 17 버전 이상)
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        
          enum EColor{	
              COLOR_WHITE,
              COLOR_BLACK,
              COLOR_YELLOW
          };
          typedef enum EColor color_t; //enum도 typedef 가능!
        			
          const char* GetColorName(color_t EnumColor){
          //enum 문자열 반환함수
              switch(EnumColor){
        				
                  case 0:
                      return "white";
                  case 1:
                      return "black";
                  case 2:
                      return "yellow";
                  default:
                      return "";
              }
          }
          typedef struct
          {
              int Wheels;
              color_t Color;
              int Year;
          }Car_t;
          void printInfo(Car_t tempCar){
                  printf("%d %s %d", tempCar.Wheels, GetColorName(tempCar.Color), tempCar.Year);
          }
          int main(){
              Car_t Trucks[2] = {{4,COLOR_WHITE, 2016},{6,COLOR_YELLOW, 2012}};
              printInfo(Trucks[1]); //6 yellow 2012 출력
          }
        
This post is licensed under CC BY 4.0 by the author.