C++ 메모리

mohadang·2022년 12월 4일
0

C++

목록 보기
37/48
post-thumbnail

stack

예약된 메모리 공간(보통 1mb) 이하, 컴파일 시점에 컴파일러가 스택을 얼마만큼 할당 할 지 지정함.
컴파일러 옵션으로 할당할 스택 메모리 크기 지정 가능
함수 호출과 반환이 이 메모리에서 일어남

단순히 스택 포인터를 옮김

사용자가 메모리를 할당 및 해제할 필요가 없음
스택에 할당된 메모리는 범위(scope)를 벗어나면 사라짐
변수와 매개변수를 위해 필요한 크기는 컴파일 도중에 알 수 있음

Heap 처럼 런타임중에 메모리 위치로 가서 Chain 을 검색하며 메모리 내용에 해제된 메모리라고 표시하면서 해제할 필요 없음

스택은 단순히 스택 포인터만 옮기면 끝
지만 스택에 큰 객체를 많이 넣으면 스택 오버플로우가 발생할 수 있음 성능이 느려 질 수도 있음

heap

컴파일때 메모리가 얼마나 있는지 알 수 없다. 런타임 중에 알 수 있다.
전역 메모리 공간
비어 있고 연속된 메모리 블록을 찾아야 함
프로그래머가 메모리를 직접 할당 및 해제해야 함. 그렇지 않으면, 메모리 누수 발생. C++은 언매니지드 언어.

delete

Vector* a = new Vector();
Vector** arr = new Vector*[10];

delete a;
delete[] arr;
//배열 delete 할 때 잘 구분해서 [] 붙여주어야 함.  

RAII(Resource Acquisition Is Initialization)

Resource Acquisition Is Initialization(Resource 획득은 초기화다)
사실 callee 안에서 new를 하는것은 좋은 방법은 아니다...
함수 내에서 리소스를 할당 하였다면 그 리소스를 해제하는 책임은 그 함수이다.

void PrintVector(const Vector& a, const Vector& b) {
  Vector* result = new Vector();
    :
    :
  delete result;
}

메모리를 할당하고 이를 해제하는 역할을 다른 함수에게 맡겨버리는 구조는 메모리 누수 위험이 있다.
그러나 어쩔 수 없이 이런 구조를 사용해야 하는 경우도 ....
Factory Pattern

Factory.CreateObject();

메모리 초기화

Java, C#

public class Vector
{
  private int x;
  private int y;
}

C++

class Vector {
private:
  int mX;
  int mY;
};

struct Vector {
  int mX;
  int mY;
};

Java, C#, 최근 언어이다. x,y는 모두 0으로 초기화
C++은 쓰레기값 들어 있음. 0으로 초기화를 안하는 이유는 오로지 '성능'

//Java도 C++로 만들었으니...
Vector a = new Vector();
  |
  V
void* ptr = malloc(sizeof(Vector));
memset(ptr, 0, sizeof(Vect0r));
a = (Vector*)ptr;

생성자의 주 역할은 메모리 초기화이다

Java, C#

public class Vector {
  private int x;
  private int y;
  public Vector() {
    // Java는 0으로 초기화를 하기 위한 생성자가 필요 없음
    x = 0;
    y = 0;
  }
}

C++

class Vector
{
public:
  Vector() {
    // C++는 초기화 생성자가 필요하다, 이유는 초기화 안하면 쓰레기 값이기에
    // 하지만 이런 초기화는 권고되지 않는다.
    // C++에서는 초기화 리스트 사용을 강하게 권고한다.
    mX = 0;
    mY = 0;
  }
private:
  int mX;
  int mY;
};
profile
mohadang

0개의 댓글