구조체
Struct
여러 자료형을 가진 변수를 하나 이상 묶어 새로운 자료형을 정의하는 것
클래스와 매우 유사한 형태를 지님
구조체와 클래스의 차이
구조체와 클래스의 차이점은 선언명이 다르다는 것이다. 구조체는 struct 키워드로 선언하고, 클래스는 class 키워드로 선언한다.
또 다른 차이로는 접근 지정자가 없을 때, default 접근 지정자가 다르다. struct는 접근 지정자가 없을 시, public으로 간주되고, class는 private으로 간주된다.
구조체의 특징
구조체의 특징으로는 여러 타입의 변수를 하나의 구조체로 묶을 수 있다는 것과, 메모리 공간을 연속적으로 사용한다는 것이 있다.
타입에 상관 없이 여러 자료형의 변수들을 한데 묶을 수 있고, 구조체 내부에 함수를 선언할 수도 있다.
구조체는 정의한 변수들을 연속적인 메모리 공간에 보관한다. 그런데 이때 패딩이 발생한다. 패딩이란, 여러 자료형의 변수들 중 가장 큰 크기의 자료형에 맞춰 메모리 공간을 할당하는 것이다.
패딩의 예시를 한 번 보자.
예시
struct StructSize
{
short shortSize; //2
int intSize; //4
float floatSize; //4
char charSize; //1
};
각각의 크기는 위에서부터 각각 2바이트, 4바이트, 4바이트, 1바이트 순이다.
이 구조체의 크기는 얼마일까 생각보면 2 + 4 + 4 + 1인 11바이트라고 생각할 수 있다.
하지만, 이 구조체의 크기는 16바이트이다.
그 이유는 바로 방금 위에서 언급했던 패딩 때문이다.
short와 char 자료형은 가장 큰 int와 float 자료형에 맞춰 메모리 공간이 할당된다.
short는 2바이트이기 때문에 뒤에 2바이트의 남는 공간이 발생한다.
그럼 또 다시 생각해보면, short와 char 뒤에는 각각 2바이트와 3바이트의 남는 공간이 생긴다는 것이다.
이 메모리 누수 현상을 최소화하기 위한 방법은 2가지가 있다. 첫 번째는 자료형을 선언하는 순서를 바꿔주면 된다.
struct StructSize
{
int intSize; //4
float floatSize; //4
short shortSize; //2
char charSize; //1
};
이런 형식으로 바꿔주게 되면, short와 char은 같은 공간 내에 2바이트와 1바이트를 차지하여 1바이트의 메모리 누수가 발생하게 된다.
이전의 예시와 비교하면 메모리 누수가 2바이트 가량 줄어들게 되는 것이다.
두 번째는 #pragma pack(byte) 이라는 키워드를 사용하는 것이다
이 키워드를 통해 정렬하고 싶은 바이트 수를 지정해 줄 수 있다.
#pragma pack(1)을 사용하면 1바이트 단위로 정렬하겠다는 의미이고, 위의 구조체의 크기는 11바이트가 된다.
그럼 메모리를 1바이트 단위로 정렬하니까 메모리 공간을 적게 쓸 수 있어서 좋은 것 아닌가?라는 생각이 들 수 있다.
물론 메모리 사용을 최소화해야 하는 경우라면 사용하는 것이 좋을 수 있다. 하지만, 구조체가 이렇게 만들어진 데에는 다 이유가 있을 것이다.
그 이유는, CPU가 가장 크기가 큰 자료형을 기준으로 블록을 구성해서 그 블록 별로 처리를 하기 떄문이다.
그렇기에, 정렬하는 바이트 수를 제한하는 것 보다는 선언하는 순서를 바꿔 사용하는 것이 좋다.