나만의 작은 도서관

[C++][Etc] 쓰레기 값에도 패턴이 있을까? 본문

C++/문법 및 메소드(STL)

[C++][Etc] 쓰레기 값에도 패턴이 있을까?

pledge24 2025. 6. 14. 17:12
주의사항: 해당 글은 다듬지 않은 날것 그대로인 글입니다. 

쓰레기 값이란?

  • 쓰레기 값이란 초기화되지 않은 메모리에 들어있는 값을 의미한다. 예를 들어, int a; 와 같이 변수를 선언만 하고 값을 초기화하지 않았다면, a에는 쓰레기 값이 들어있게 된다.
int a;
cout << a << '\\n'; // ❌ 경고 또는 예측 불가 값 (쓰레기값)
  • 물론, 전역 변수와 정적 지역 변수(static)는 사용자가 초기화를 따로 하지 않아도 자동으로 초기화되기 때문에 쓰레기값 대신 기본값이 들어있게 된다. 그렇기에 전역 변수와 정적 지역 변수는 오늘 다룰 주제에서 제외된다.

 

struct나 class의 멤버 변수의 쓰레기 값

  • struct나 class가 들고 있는 멤버 변수들은 객체가 생성될 때 자동으로 초기화될까?
  • 그렇지 않다. struct나 class의 멤버 변수도 기본 타입(int나 float 등)을 선언했을 때와 동일하게 자동으로 초기화되지 않는다. 즉, 멤버 변수를 따로 초기화를 하지 않았다면 기본값이 아닌 “쓰레기 값”이 들어있게 된다.
struct MyStruct {
    int x;
    int y;
};

struct MyClass {
public:
    int x;
    int y;
};

void func() {
    int x;
    std::cout << x << std::endl;  
}

int main() {
    MyStruct str;
    MyClass cla;

    cout << "struct: " << str.x << " " << str.y << '\\n';
    cout << "class: " << cla.x << " " << cla.y << '\\n';

    return 0;
}

 

 

실행 결과

struct: 16 0
class: 6952688 0
  • 이러한 이유로, 안전한 멤버 변수 사용을 위해 초기화를 진행한 다음 객체를 사용하는 것이 좋다. 초기화는 1) 생성자를 이용해서 하거나, 2) 클래스 내부에서 멤버 변수의 기본값을 설정하는 인클래스 멤버 초기화 방식을 이용해서 한다. (인클래스 멤버 초기화는 C++11부터 가능)
  • (참고로, 동적 할당을 해도 똑같이 자동 초기화는 하지 않는다.)
struct MyStruct {
    int x = 10; // C++11 이후 가능
    int y = 20; // C++11 이후 가능
};

struct MyClass {
public:
    int x = 30; // C++11 이후 가능
    int y = 40; // C++11 이후 가능
};

void func() {
    int x;
    std::cout << x << std::endl;  
}

int main() {
    MyStruct str;
    MyClass cla;

    cout << "struct: " << str.x << " " << str.y << '\\n';
    cout << "class: " << cla.x << " " << cla.y << '\\n';

    return 0;
}

 

 

실행 결과

struct: 10 20
class: 30 40

 

쓰레기 값에도 패턴이 있을까?

  • 쓰레기 값은 어떤 의미를 가지는 값이 아니기 때문에 값의 패턴을 해석한다는 것은 의미가 없어 보인다. 실제로 실행한 프로그램 내에서 발생한 쓰레기 값의 패턴을 분석한다는 것은 쓸데없는 짓이다.
  • 하지만 디버그 빌드 환경이라면 이야기는 달라진다. 일부 컴파일러에서는 디버그 환경에서 인위적으로 쓰레기 값을 특정한 패턴으로 채워 넣는다. 대표적으로, MSCV(Visual Studio)에서 디버그 빌드를 하면 아래와 같은 패턴으로 쓰레기 값이 들어가 있게 된다.
    • 0 xCC: 초기화되지 않은 스택 메모리
    • 0 xCD: malloc 후 초기화되지 않은 힙 메모리
    • 0 xDD: 해제된 힙 메모리
    • 0 xFE: guard byte (버퍼 오버런 감지요)
  • Visual Studio 디버그 빌드시 쓰레기 값 패턴
  • 만약 이 패턴들을 확인해보고 싶다면, MSVC에서 메모리 창을 켜서 확인해 보면 된다. 확인해보면 아래와 같은 패턴으로 메모리가 표시되는 것을 볼 수 있을 것이다.
=== 스택 변수 (초기화되지 않음) ===
cc cc cc cc

=== 힙 메모리 (malloc으로 할당, 초기화 안 함) ===
cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd

=== 힙 메모리 해제 후 접근 (해제 직후 메모리 값 확인) ===
dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd dd

 

C++ 표준도 패턴이 있을까?

  • C++ 표준에서는 쓰레기 값에 인위적인 패턴을 집어넣지 않는다. 만약 C++ 코드를 빌드하는 컴파일러 및 디버거가 C++ 표준이라면, MSVC와 같은 인위적인 패턴을 가진 쓰레기 값은 없을 것이다.