포인터 마무리, 메모리 오염

 

인프런 Rookiss님의 'Part1: C++ 프로그래밍 입문' 강의를 기반으로 정리한 필기입니다. 
😎[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part1: C++ 프로그래밍 입문 강의 들으러 가기!

 

 


 

포인터 vs 배열

 

포인터

-  주소를 담는 바구니

-  원본은 저~ 멀리 어딘가에 있음

-  p는 단지 그 곳으로 워프하는 포탈

    int* p;

 

배열

-  진짜배기! 원조 데이터
-  닭장처럼 데이터의 묶음 (엄청 많고 거대함)

    int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8 };

 

 

포인터 vs 배열

-  그런데 상당히 많은 사람들이 [배열 = 포인터]라 착각하는 경향이 있음.

-  [배열의 이름]은 배열의 시작 주소값을 가리키는 TYPE* 포인터로 변환 가능.

  • p = arr;

-  [TYPE형 1차원 배열]과 [TYPE*형 포인터]는 완전히 호환이 된다.

    p = arr;

    // - [TYPE형 1차원 배열]과 [TYPE*형 포인터]는 완전히 호환이 된다
    cout << p[0] << endl;
    cout << arr[0] << endl;
    cout << p[5] << endl;
    cout << arr[5] << endl;
    cout << *p << endl;  // p[0]
    cout << *arr << endl; // arr[0]
    cout << *(p + 3) << endl;
    cout << *(arr + 3) << endl;

실행화면

 


 

다중 포인터 vs 2차원 배열

 

    // 서로 호환이 되지 않는 타입. 잘못된 방식이다 
    // [1][2][3][4]
    int arr1[2][2] = { {1, 2}, {3, 4} };

    // 주소2 [ ]        // 4바이트
    // 주소1[ 주소2 ]    // = 주소1[ 00000001 ]
    // pp[ 주소1 ]
    int** pp = (int**)arr1;
    cout << (**pp) << endl; //에러. crash

다중 포인터와 2차원 배열은 서로 호환이 되지 않는 타입이다.

위와 같은 방식으로 사용할 수 없다.


 

 

 

포인터 표현을 사용하여 2차원 배열 나타내기

 

int main()
{
    // [1][2][3][4]
    int arr2[2][2] = { {1, 2}, {3, 4} };

    // TYPE name[개수]

    // [1][2][3][4]
    // [ 주소 ]
    int(*p2)[2] = arr2;
    cout << (*p2)[0] << endl;
    cout << (*p2)[1] << endl;
    cout << (*(p2 + 1))[0] << endl;
    cout << (*(p2 + 1))[1] << endl;

    cout << p2[0][0] << endl;
    cout << p2[0][1] << endl;
    cout << p2[1][0] << endl;
    cout << p2[1][1] << endl;

    return 0;
}

 

실행화면


 

 

 

메모리 오염

 

#include <iostream>
using namespace std;

int& TestRef()
{
    int a = 1;
    return a;
}

int* TestPointer()   // 메모리 오염 예시
{
    int a = 1;  // 함수의 생명주기를 잘 생각하자
    return &a;  // 내부에만 유효한 주소값을 밖으로 넘겨주는 행위는 절대 하지말자. 
}

void TestWrong(int* ptr)
{
    int a[100] = {};
    a[99] = 0xAAAAAAAA;
    *ptr = 0x12341234;
}

int main()
{
    // [매개변수][RET][지역변수] 
    // [매개변수][RET][지역변수] [매개변수][RET][지역변수(a)]
    int* pointer = TestPointer();

	//*pointer = 123;  // 엉뚱한 메모리를 건드리는 경우

    TestWrong(pointer);

    return 0;
}

 

 

실행화면

 

&(a[99])
*ptr&nbsp; &nbsp; 엉뚱한 메모리를 건드림
Debug 모드에서 에러가 발생함. 하지만 Release 모드에서는 실행된다. 이 점을 유의하자.