본문 바로가기

Today I Learned

23.01.30 - 공용체, 동적 할당

공용체 

union 
{
    int a;
    float b;
    short s;
} un;

공용체는 구조체와 사용하는 문법이 동일하다. 다른 점은 모든 멤버 변수가 메모리를 공유해서 사용한다는 것이다.

공용체의 크기는 멤버 변수중 가장 큰 자료형의 크기 만큼만 할당한다. (위 un의 크기 4바이트)

멤버 변수 하나의 값만 바뀌어도 전체 멤버 변수의 값이 바뀐다.

	un u = { 4 };
	cout << u.b; //5.60519e-45

공용체는 초기화 할 때 값 하나만 넣을 수 있다. 위 코드는 공용체 메모리를 4로 초기화 하고 float형 멤버 변수 b를

출력했는데 이상한 값이 나온다. 이는 실수형이 정수형과 데이터를 저장하는 방식이 다르기 때문이다.

union tag_unit {
     int mili;
     double inch;
};

그렇다면 공용체를 사용하는 이유는 무엇일까? 위 공용체 tag_unit은 길이를 표현하는데 정수로 표현하고 싶으면

int형 변수 mili, 실수로 표현하고 싶으면 double형 변수 inch를 사용한다. 이렇게 하나의 데이터를 여러가지 방법으로 표현할 때 사용할 수 있다. 하지만 tag_unit에 저장된 데이터가 정수인지 실수인지 구분하는 방법은 없다. 

 

 

 

동적 할당

동적 할당이란 런타임 (프로그램 실행) 중에 메모리를 할당하는 것이다.

int* p = (int*)malloc(sizeof(int));

int* p2 = (int*)calloc(4,sizeof(int));

malloc, calloc 두 방법으로 동적 할당이 가능하다. 두 함수는 void형 포인터를 반환하는 함수인데, 어떤 자료형인지

정해져 있지 않은 자료형으로 대입할 때 대입하는 변수의 자료형으로 형 변환을 해줘야 한다. calloc은 배열 느낌으로

매개변수(개수, 크기)로 크기만큼 연속적인 개수로 이어진 메모리를 할당하고 모두 0으로 초기화한다.

free(p);
p = nullptr;

free함수로 동적 할당한 메모리를 해제할 수 있다. 그 후 포인터를 nullptr로 만들어줘야 하는데 그 이유는

메모리를 해제하고 나서도 포인터를 통해 메모리에 접근하고 쓸 수 있다. 이 포인터를 댕글링 포인터라고 한다.

댕글링 포인터를 방지하기 위해 해제한 메모리의 포인터를 널포인터로 꼭 바꿔줘야 한다.