본문 바로가기
C,C++/C++

[C++] 클래스의 멤버가 저장되는 영역 및 메모리 차지

by woohyeon 2020. 1. 10.
반응형

클래스 사용 도중 헷갈리던 내용이 있어서 정리함.

함수 내에서 임시로 객체를 생성할 때 사용 용도에 따라 비효율적인 부분이 있는지 헷갈려서 instance 생성 시 각 멤버들이 어떻게 메모리를 차지하는지 개념을 정리하기 위한 글.

우선 class는 멤버 변수와 멤버 함수를 가질 수 있고 각각 정적(static)과 비정적(non-static) 멤버 변수, 함수를 가질 수 있다.

 


출처: http://tcpschool.com/c/c_memory_structure

 

먼저 클래스 타입의 객체 또는 인스턴스 자체의 크기는 비정적 멤버 변수만 영향을 미친다. 즉 멤버 변수로 int형 변수 1개를 가지면 이 클래스의 instance의 sizeof는 4바이트, 2개를 가지면 8바이트 이런 식. 비정적 멤버 변수는 객체의 생성과 동시에 생성된다. 객체 내의 지역 변수와  동일하므로 스택에 저장된다.  (물론 동적으로 할당되는 메모리는 heap 영역에 저장됨)
또한 비정적 멤버 변수는 클래스 내에서 공유되는 변수가 아닌 하나의 객체마다 할당되는 변수이다.

만약 클래스 내에 정적 멤버 변수를 선언했다면 이 변수는 객체 생성 시 할당되는 것이 아니라 프로그램 시작 시 데이터 영역에 생성된다. 따라서 정적 멤버 변수는 객체의 크기에 영향을 미치지 않는다. int형 변수 2개와 static int형 변수 1개를 멤버로 가지는 클래스를 예로 들면, 프로그램 시작 시 static int 타입 변수가 하나 생성되며, 해당 객체를 생성할 때 int형 변수 2개를 가진 객체가 생성된다. 이 객체의 sizeof는 8바이트다.  정적 멤버 변수는 객체마다 할당되는 변수가 아니기 때문에 해당 클래스로 생성되는 모든 객체가 공유하는 1개의 변수이며 프로그램 시작 시 데이터 영역에 저장된다.

다음은 멤버 함수이다. 멤버 함수도 동일하게 정적과 비정적으로 나뉘며 멤버 함수는 정적, 비정적 모두 객체의 크기에 영향을 미치지 않는다. 멤버 함수는 모두 code 영역에 저장되며 멤버 함수는 객체마다 다르게 동작하는 것이 아니기 때문에 객체마다 함수가 할당되면 비효율적일 것이다. 따라서 해당 클래스의 모든 객체는 code 영역에 있는 멤버 함수를 공유하며 사용한다.

정적 멤버 함수는 객체 생성 시가 아닌 프로그램 시작 시 code 영역에 저장되기 때문에 객체를 생성하지 않아도 사용할 수 있어야 한다. 따라서 클래스의 이름을 통해 접근할 수 있으며, 당연히 객체의 이름을 통해서도 접근이 가능하다. 참고로 정적 멤버 함수에서 비정적 멤버 변수 또는 비정적 멤버 함수를 사용할 순 없다. 이는 메모리가 생성되는 순서를 생각해보면 당연한 일.

이제 간단한 클래스 또는 구조체를 통해 메모리 상에 어떻게 저장되는지 확인해보자.

다음 구조체는 4바이트 멤버 변수를 3개 가진다.

struct Foo
{
	uint32_t mUnsignedInteger;
	int32_t  mSignedInteger;
	float	 mFloatingPoint;
};

 

위 구조체의 객체는 다음과 같은 메모리 구조를 가진다.

                 Foo 구조체의 메모리 구조

 

기존 구조체에 static 멤버 변수를 추가하였다.

struct Foo
{
	uint32_t        mUnsignedInteger;
	int32_t         mSignedInteger;
	float	        mFloatingPoint;
	static uint32_t mStaticInteger;
};

 

 하지만 위에서 말했듯이 정적 멤버 변수는 프로그램 시작 시 데이터 영역에 생성되기 때문에 객체의 메모리에 영향을 미치지 않는다. 따라서 동일한 메모리 구조를 가진다.

                 Foo 구조체의 메모리 구조

 




댓글