C++ Vector와 자유영역


##Vector와 자유영역

주소

  • 우리가 메모리에 저장하는 모든 변수는 주소가 있다.
  • 보통의 경우 int는 4바이트, char은 1바이트 등등
  • 따라서 프로그램에 존재하는 객체들은 각기 다른 메모리 크기와 주소값을 갖게된다.

메모리

프로그래머가 다루게 되는 메모리에 대해서 잠깐 알아보려고 한다. C++ 프로그램이 시작되면 컴파일러는 코드를 저장할 메모리와 전역변수를 저장할 메모리를 마련한다. 함수 호출에 필요한 인자와 지역 변수를 저장할 공간도 마련된다. 나머지 메모리 영역은 잠재적으로 다른 용도에 사용할 수 있다. 즉 자유로운 상태이다.

  • 코드 저장 메모리
  • 실제 코드가 저장되는 code storage 영역
  • text가 저장되는 text stroage 영역
  • 전역 변수 메모리
  • static storage
  • 함수 호출 인자 및 지역 변수 메모리
  • stack 영역

자유 영역 할당

new 연산자는 자유 저장 영역에 메모리 할당을 요청한다.

  • new 연산자는 할당한 메모리를 가르키는 포인터를 반환한다.
  • 포인터의 값은 할당한 메모리의 첫 번째 바이트의 주소다
  • 포인터는 지정한 타입의 객체를 가르킨다
  • 포인터만으로는 그 포인터가 가리키는 요소의 개수를 알 수 없다.
int* pi = new int; // int 1개 할당
double* qi = new double[n]; // n개의 int 할당

  • int형을 가르키고 싶으면 int형 포인터인 int*로 가르켜야 하고 마찬가지로 double형을 가리키고 싶을 때 double형 포인터 double*를 사용해서 가르켜야 한다.
  • 이러한 할당은 실제 실행시간에 할당되기 때문에 위에서처럼 변수 n을 사용해서 할당할 수도 있다.

포인터의 문제점들

  • 포인터만으로는 그 포인터가 가르키는 객체의 개수를 알 수 가 없다.
  • 따라서 실제 할당되지도 않은 메모리에 의도치않게 접근하는 게 가능하고 심각한 그리고 디버깅하기 어려운 에러들을 만들게 된다.
예 
double* pd = new double[3];
pd[2] = 2.2;
pd[4] = 1.1; // 실제로 할당하지 않은 메모리이지만 포인터는 이를 구분하지 못하고 메모리에 접근해 값을 바꾸게된다.  

delete

delete를 사용해서 new로 할당한 객체의 메모리를 해제해줘야 다른 곳에서도 사용할 수 있다. 사용하지 않는 변수 메모리를 해제시키지 않으면 메모리 누수를 겪게된다.

delete p // new로 할당한 객체 하나를 해제
delete[] p //new로 할당한 객체의 배열을 해제.

소멸자

  • 소멸자는 객체의 멤버에 할당한 메모리를 해제해주기 위해서 사용된다.
  • 객체를 delete할 때마다 객체의 모든 멤버에 일일히 delete를 해주기 힘들기 때문에 소멸자를 사용해서 한번에 delete를 수행한다.
  • 백터가 유효 범위 밖으로 사라지면 벡터를 자동으로 정리한다.
  • 백터에 delete를 수행하면 소멸자가 작동한다.

void 포인터

  • 컴파일러가 모르는 타입의 메모리를 가리키는 포인터
  • void*가 무엇을 가리키는지 모르기 때문에 사용시 반드시 탕
  • static_cast<int*>()를 사용해서 명시적 변환

vector

vector가 얼마나 편리한 클래스인지 알아보도록 하겠다. 백터 객체는 약 24바이트 크기로 구성되어있다.

vector<int> v(1000);
sizeof(v)  // 24





© 2017. by yunsu

Powered by dolphin