본문 바로가기
c++

사소한 부분에서 메모리를 아끼는법을 알아보자.

by chunma1126 2025. 3. 10.

 

c++를 하다보면 아주 작은 부분들을 고치는것만으로도 메모리를 아낄수 있다는걸 알게된다.

오늘은 내가 공부한 아주 사소한 부분들을 공유해보도록 하겠다.

복사

#include <iostream>
using namespace std;

class Entity 
{
public:
    Entity() 
    {
        cout << "create Entity!" << endl;
    }
    Entity(const Entity& other)
    {
        cout << "create Entity!" << endl;
    }
    int health;
};

void PrintEntity(Entity e) 
{
    cout << "health : " << e.health << endl;
}

int main()
{
    Entity e;
    e.health = 10;

    PrintEntity(e);


    return 0;
}

 

다음과 같은 코드가 있을때 createEntity가 몇번 호출될까?

생성되는 객체가 하나밖에 없으니까 한번이라고 생각했다면 크나큰 오산이다.

 

PrintEnemy에서 Entity 객체를 복사로 전달하고 있기 때문에 총2번 생긴다.

PrintEnemy는 단순히 Entity의 값을 읽기만 하고 있기 때문에 굳이 복사로 가져올 이유가 없다.

때문에 참조에 의한 전달로 바꾸면 더 효율적으로 동작하게 만들수 있다.

void PrintEntity(const Entity& e) 
{
    cout << "health : " << e.health << endl;
}

이렇게 말이다.

 

이제 createEntity도 한번밖에 뜨지 않는다!

 

member initalizer

#include <iostream>
using namespace std;

struct Vector
{
    Vector() : x(0), y(0) 
    {
        cout << "create Vector (default)" << endl;
    }

    Vector(int x, int y)
    {
        this->x = x;
        this->y = y;
        cout << "create Vector" << endl;
    }

    Vector(const Vector& other) 
    {
        x = other.x;
        y = other.y;
    }

    int x, y;
};

class Entity
{
public:
    Entity(Vector defaultPostion) 
    {
        postion = defaultPostion; 
    }

    Vector postion;
    int health;
};

int main()
{
    Entity({1,2});
    return 0;
}

다음과 같은 코드가 있을때 

 

CreateVector가 2번 나온다!

왜 그런지 알겠는가?

 

변수는 처음에 선언될때 초기화 된다.

때문에 저때 한번 기본 생성자가 불러지면서 create되는것이다.

그리고 복사로 가져와서 한번더 할당 되고...이런 이런 메모리 낭비가 너무 심하잖아..

 

때문에 멤버 이니셜라이즈를 사용하면 기본 생성자가 출력되는 부분이 생략되기 때문에 할당을 한번 줄일수 있는것이다!

 

String

int main()
{
    string str = "string";
    string a = "sss";
    
    a = a + str;

    return 0;
}

다음과 같은 코드에도 문제가 있다.

대입 전에 먼저 sss + str 가 먼저 일어나서 sssstr라는 새로운 객체가 생성된다.

 

그리고 나서 a에 대입되기 때문에 쓸때없는 객체를 하나 만드는꼴이다.

아주 간단하게 해결할수 있다. 바로 복합 대입 연산자를 사용하는것이다.

int main()
{
    string str = "string";
    string a = "sss";

    a += str;

    return 0;
}

 

이렇게 하면 새로운 객체가 생성되지 않고 바로 a에 추가되기 때문에 쓸때없는 할당을 한번 줄일수 있는것이다!

 

Vector

벡터를 만들때 가장 많이들 하는 실수가 바로 미리 크기를 지정하지 않는것이다.

벡터를 만들때 처음 크기를 지정하지 않으면 현재 배열에 값을 넣을때 범위 검사를 하고 내부적으로 메모리 크기를 늘리기 때문이다.

 

for (int i = 1; i <= 10; i++) {
    v.push_back(i);
    std::cout << "size: " << v.size() << ", capacity: " << v.capacity() << '\n';
}

 

다음과 같은 코드가 있을때 필요할때마다 Vector를 조금씩 늘린다.

 

처음만들어 줄때부터 reverse()를 활용해서 늘리던가, 생성자가 capacity를 넣어주면 된다.

두 기능의 차이는 생성자에서 초기화 해주면 값이 다 0으로 들어가 있지만 reverse()를 하면 메모리만 할당하기 때문에 접근하면 오류가 난다.

    vector<int> vec(5);
    vec.reserve(5);

 

 

 

오늘은 사소하지만 메모리를 아낄수 있는 방법들에 대해 알아보았다.

이런 작지만 사소한것들이 모여 프로그램 전체에 영향을 줄수 있다!

 

꺼진 불씨도 다시보는 습관을 기르도록 하자!!