BumCode

구조체

클래스의 원시형태라고 할 수 있는 C언어의 구조체에 대해 알아보자.
구조체는 사용자 정의 자료형이라 이해하면 된다.

구조체의 정의 및 변수선언

구조체의 정의는 다음과 같다.

struct Car{
	char name[10];
	int year;
};

위와 같이 구조체를 정의했다면 구조체 변수 선언은 다음과 같다.

//구조체 정의시의 변수 선언(구조체 정의와 동시에 변수를 생성함)
struct Car{
	char name[10];
	int year;
}car1,car2,car3;

//함수 내에서 구조체 변수의 선언
struct Car car1, car2, car3;

변수 선언 시 매번 struct를 붙이는게 싫다면, typedef를 사용하면 된다.

typedef struct Car{
	char name[10];
	int year;
}C;

struct Car 를 C로 사용하겠다는 의미로, 우리가 long long을 간단하게 ll로 사용하고자 할 때 typedef long long ll; 처럼 사용하는 것처럼 말이다. 이제 변수 선언시에 다음과 같이 간단하게 할 수 있다.

C car1, car2, car3;

구조체 변수의 초기화

변수 선언시에 배열과 같이 { }를 사용하여 초기화할 수도 있고 하나씩 초기화해주는 것도 가능하다.

C car1={"sonata",2010};

C car2;
strcpy(car2.name, "sonata");
car2.year = 2010;

구조체의 메모리 할당

구조체의 멤버변수가 다음과 같다고 하자.
int, int, char
4+4+1 byte이므로 크기가 9byte라고 생각 할 수도 있겠지만, 구조체에선 그렇지 않다.
구조체 메모리 할당 시 멤버변수 중 크기가 가장 큰 변수의 자료형 을 기준으로 메모리를 할당하기 때문이다. 위에선 int가 4byte로 가장 큰 자료형이니 4byte씩 할당되어 4+4+4 = 12byte가 된다.

주의할 점은 멤버가 같다고 해도 순서가 다르다면 크기가 달라진다.

struct A {	//12byte
	char a;
	int b;
	char c;
}; 

struct B {	//8byte
	char a;
	char c;
	int b;
}; 

우선 A와 B 모두 가장 큰 자료형은 int로 4byte이다.

  • A의 경우
    char a를 4바이트 공간에 할당한 뒤, 다음 4바이트에 int b를, 다음 4바이트에 char c를 할당한다.
  • B의 경우
    char a를 4바이트 공간에 할당한 뒤, (a는 1바이트만 사용하니 3바이트가 남는다) 다음 char c는 1바이트로 남은 3바이트 공간에 들어갈 수 있기때문에 char a와 char b는 연속된 메모리에 저장 된 후, 남은 남은 2바이트를 건너뛰고 int b를 다음 4바이트에 할당한다.

다른 예시를 보자.

struct A {
	char a[12];
	int b;
	double c;
};

struct B {
	char a[13];
	int b;
	double c;
};

여기서 A와 B의 구조체 변수의 크기는 어떻게 될 것 같은가?

  • A의 경우
    가장 큰 자료형 double : 8byte
    char a[12]는 12byte이며, 8byte씩 할당되니 16byte공간에 a가 할당된다.
    16의 공간에 12가 할당되었으니 4byte가 남는다.
    다음 멤버변수인 int b의 크기는 4byte로 남은 공간에 들어 갈 수 있다. 그렇기에 처음 16byte에 a와b가 꽉 차게 들어가며, 다음 8byte에 double c가 들어가 24byte가 된다.

  • B의 경우
    가장 큰 자료형 double : 8byte
    char a[13]은 13byte로 처음 8+8, 16byte크기로 할당된다.
    16공간에 13이 할당되었으니 3byte가 남는다.
    다음 멤버인 int b는 4byte로 3byte 공간에 들어 갈 수 없기에 3바이트는 건너뛴다. 다음 8byte 공간에 int b가 할당되고 4byte가 남는다. 4byte에 double c : 8byte가 들어 갈 수 없으니 4byte는 건너뛰고 다음 8byte에 double c가 들어가 32byte가 된다.

구조체의 메모리 할당방식때문에 메모리낭비를 없애고 효율적으로 할당하려면 순서를 신경써 변수를 선언해주는 것이 좋다.