본문 바로가기
C++ 200제/코딩 IT 정보

C++ 메모리 해제와 접근 할당 에러 9가지 적절한 malloc 사용법

by vicddory 2017. 2. 5.

C++ 메모리 해제 접근 할당 에러 (malloc, delete, free) 


C++ 메모리 에러 종류

1. 메모리 해제 에러

메모리 릭

  • 시간이 갈수록 메모리 사용량이 계속 증가한다. 시간이 갈수록 프로세스가 느리게 동작한다.

종국적으로 『메모리가 부족』하여 프로그램의 작업과 시스템 콜들이 실패한다.


1
2
3
4
5
6
void memoryLeak()
{
    int* p = new int[1000];
 
    return// 버그! p를 해제하지 않음
}
cs



C++ 메모리 해제 에러C++ 메모리 할당 해제 에러


메모리 할당, 해제의 잘못된 매칭


보통 프로그램을 즉시 크래시시키지 않는다. 어떤 플랫폼에서는 메모리를 손상할 수 있고 나중에 프로그램 크래시(세그먼테이션 오류)로 나타난다.


1
2
3
4
5
6
7
8
9
10
11
void mismatchedFree()
{
    int* p1 = (int*)malloc(sizeof(int));
    int* p2 = new int;
    int* p3 = new int[1000];
 
    delete p1; // 버그! free를 사용해야 함
    delete p2; //버그! delete를 사용해야 함
 
    free(p3); 버그! delete[] 를 사용해야 함
}
cs


중복된 메모리 해제


두 delete 명령 중간에 다른 코드에서 해당 메모리를 할당받으면 중복 delete 후 그 메모리에 접근할 때 프로그램이 크래시(세그먼테이션 오류)된다.


1
2
3
4
5
6
7
8
void doubleFree()
{
    int* p1 = new int[1000];
    delete[] p1;
 
    int* p2 = new int[1000];
    delete[] p1; // 버그! p1을 두 번 해제했음
}
cs



C++ malloc delete freeC++ 메모리 할당 해제 에러



할당되지 않은 메모리의 해제


보통 프로그램이 크래(세그먼테이션 오류 또는 버스 에러)된다.


1
2
3
4
5
void freeUnallocated()
{
    int* p = reinterpret_cast<int*>(10000);
    delete p; // 버그! p는 유효한 포인터가 아님
}
cs


스택 메모리의 해제


기술적으로 할당되지 않은 『메모리를 해제』하는 것과 같다. 보통 프로그램이 크래시된다.


1
2
3
4
5
6
void freeStack()
{
    int x;
    int* p = &x;
    delete p; // 버그! 스택 메모리를 해제함
}
cs


위 문제의 대부분은 일반 포인터 대신 스마트 포인터를 사용함으로써 회피될 수 있다.



2. 메모리 접근 에러

에러 종류

잘못된 메모리 접근


대부분은 프로그램이 즉시 크래시 된다.


1
2
3
4
5
void accessInvalid()
{
    int* p = reinterpret_cast<int*>(10000);
    *= 5 // 버그! p는 유효한 포인터가 아님
}
cs



C++ 메모리 해제 에러C++ 메모리 할당 해제 에러



해제된 메모리에 접근


보통 프로그램이 크래시되지 않는다. 만약 메모리가 다른 곳에 전달된 경우 예상치 못한 이상한 값이 나타날 수 있다.


1
2
3
4
5
6
7
8
9
10
void accessFreed()
{
    int* p1 = new int;
    delete p1;
 
    int* p2 = new int;
    delete p1;
 
    *p1 = 5// 버그! p1에 의해 포인팅되는 메모리는 이미 해제되었음
}
cs



C++ 메모리 해제 접근 할당 에러C++ 메모리 할당 해제 에러



다른 곳에서 할당한 메모리에 접근


프로그램이 크래시되지는 않는다. 예상치 못한 이상한 값이 나타날 수 있다.


1
2
3
4
5
6
7
8
9
10
void accessElsewhere()
{
    int x, y[10], z;
    x = 0;
    z = 0;
 
    for (int i = 0; i <= 10; i++) {
        y[i] = 5// 버그! 1 == 10에 해당하는 항목은 배열의 경계를 벗어남
    }
}
cs


초기화되지 않은 메모리 읽기


초기화되지 않은 값을 잘못 이용하지 않는다면(ex: 포인터로서 역참조) 프로그램이 크래시되지는 않는다. 심지어 잘못 이용했는데도 크래시되지 않을 때가 있다.


1
2
3
4
5
void readUninitialized()
{
    int* p;
    cout << *p; // 버그! p는 초기화된 적이 없음
}
cs


 출처 : 전문가를 위한 C++ 2권, 1213~1215

C++ 메모리 해제 접근 할당 에러 (malloc, delete, free)

댓글