본문 바로가기

IT

[C++ 포인터 구조] 기본 개념과 동적 메모리 할당

반응형

C++에서 포인터(Pointer)는 매우 중요한 개념으로, 변수나 데이터의 메모리 주소를 저장하는 변수입니다. 포인터를 사용하면 메모리의 효율적인 관리가 가능하고, 동적 메모리 할당과 같은 고급 기능을 사용할 수 있습니다.

포인터의 구조와 사용법에 대해 자세히 설명하겠습니다.

1. 포인터의 기본 개념

포인터는 변수의 메모리 주소를 저장하는 변수입니다. C++에서 변수는 메모리 상에 데이터를 저장하는 공간을 가지고 있는데, 포인터는 그 주소를 저장합니다.

포인터의 구조:

  • 포인터는 * 연산자를 사용하여 선언하며, 이는 해당 변수는 주소를 가리킨다는 의미입니다.
  • 포인터는 특정 타입의 변수만을 가리킬 수 있습니다. 예를 들어, int 타입 포인터는 int 변수의 메모리 주소만 가리킬 수 있습니다.
cpp
코드 복사
int x = 10; // 정수형 변수 x int* ptr = &x; // x의 주소를 저장하는 포인터 ptr

설명:

  • &x는 변수 x의 메모리 주소를 반환합니다.
  • ptr는 x의 메모리 주소를 저장하는 포인터입니다.
  • ptr을 사용하여 x의 값을 간접적으로 접근할 수 있습니다.

2. 포인터 선언 및 사용

포인터는 타입과 함께 선언됩니다. 예를 들어, int* ptr은 int 타입을 가리키는 포인터입니다. 이를 통해 변수의 메모리 주소를 저장하고, 그 주소를 통해 변수에 접근할 수 있습니다.

포인터 선언

cpp
코드 복사
int* ptr; // int 타입을 가리키는 포인터 선언

포인터 사용 예시

#include <iostream>
using namespace std;

int main() {
    int a = 5;       // 일반적인 정수형 변수
    int* ptr = &a;   // a의 주소를 ptr에 저장 (포인터 선언)

    cout << "a의 값: " << a << endl;           // a의 값 출력
    cout << "ptr이 가리키는 값: " << *ptr << endl; // ptr이 가리키는 값을 출력 (간접 참조)
    cout << "a의 주소: " << &a << endl;       // a의 주소 출력
    cout << "ptr의 값 (주소): " << ptr << endl; // ptr이 저장한 주소 출력

    return 0;
}

설명:

  • &a: a의 메모리 주소를 가져옵니다.
  • *ptr: ptr이 가리키는 주소에 저장된 값을 간접적으로 참조합니다.
    • *ptr은 포인터 ptr이 가리키는 위치의 값을 반환합니다.

3. 간접 참조 (Dereferencing)

간접 참조는 포인터가 가리키는 메모리 주소에 저장된 값을 읽거나 수정하는 과정입니다. * 연산자는 포인터를 통해 간접적으로 변수에 접근할 때 사용됩니다.

예시: 간접 참조

#include <iostream>
using namespace std;

int main() {
    int num = 100;
    int* ptr = &num;

    // 포인터를 통해 간접적으로 값 변경
    *ptr = 200;  // ptr이 가리키는 값 변경 -> num의 값이 200로 변경

    cout << "num의 값: " << num << endl; // 200 출력

    return 0;
}

설명:

  • *ptr = 200;는 ptr이 가리키는 num 변수의 값을 200으로 변경합니다. 즉, num의 값은 200으로 업데이트됩니다.

4. 포인터와 배열

배열의 이름은 배열의 첫 번째 요소의 주소를 가리키는 포인터로 취급됩니다. 따라서 배열을 포인터처럼 다룰 수 있습니다.

배열과 포인터

#include <iostream>
using namespace std;

int main() {
    int arr[] = {10, 20, 30, 40, 50};
    int* ptr = arr; // 배열의 첫 번째 요소의 주소를 포인터 ptr에 저장

    // 배열 원소를 포인터를 통해 접근
    for (int i = 0; i < 5; i++) {
        cout << "arr[" << i << "] = " << *(ptr + i) << endl;  // ptr + i는 배열 요소의 주소
    }

    return 0;
}

설명:

  • arr은 배열의 첫 번째 요소의 주소를 가지고 있습니다. 따라서 ptr을 배열처럼 사용할 수 있습니다.
  • *(ptr + i)는 배열의 각 요소에 접근하는 방식입니다. ptr + i는 ptr에서 i만큼 떨어진 메모리 주소를 의미합니다.

5. 포인터의 크기

포인터 변수의 크기는 포인터가 가리키는 데이터 타입에 상관없이 주소 크기와 동일합니다. 보통 64비트 시스템에서는 8바이트입니다.

#include <iostream>
using namespace std;

int main() {
    int* ptr;
    double* ptr2;

    cout << "int 포인터 크기: " << sizeof(ptr) << " 바이트" << endl;   // 보통 4바이트 또는 8바이트
    cout << "double 포인터 크기: " << sizeof(ptr2) << " 바이트" << endl; // 보통 4바이트 또는 8바이트

    return 0;
}

설명:

  • sizeof(ptr)는 포인터가 가리키는 타입의 크기와 관계없이 포인터 자체의 크기를 반환합니다. 포인터는 메모리 주소를 저장하므로, 포인터의 크기는 시스템의 아키텍처에 따라 다를 수 있습니다.

6. 포인터와 동적 메모리 할당

C++에서는 new와 delete 연산자를 사용하여 동적 메모리 할당메모리 해제를 할 수 있습니다.

예시: 동적 메모리 할당

#include <iostream>
using namespace std;

int main() {
    int* ptr = new int;  // 동적 메모리 할당
    *ptr = 50;           // 할당된 메모리에 값 대입

    cout << "동적 할당된 값: " << *ptr << endl; // 50 출력

    delete ptr;  // 동적 메모리 해제

    return 0;
}

설명:

  • new int는 int 타입을 위한 메모리 공간을 동적으로 할당합니다.
  • delete ptr은 동적으로 할당한 메모리를 해제합니다. 메모리 누수를 방지하기 위해 delete를 사용하여 할당한 메모리를 반드시 해제해야 합니다.

7. 포인터 배열

포인터 배열은 여러 개의 포인터를 저장할 수 있는 배열입니다. 예를 들어, 문자열을 가리키는 포인터들의 배열을 만들 수 있습니다.

예시: 포인터 배열

#include <iostream>
using namespace std;

int main() {
    const char* fruits[] = {"Apple", "Banana", "Cherry"};

    for (int i = 0; i < 3; i++) {
        cout << fruits[i] << endl; // Apple, Banana, Cherry 출력
    }

    return 0;
}

설명:

  • fruits는 문자열을 가리키는 포인터의 배열입니다. 각 포인터는 문자열을 가리킵니다.

8. 포인터와 함수

함수에 포인터를 전달하여 값의 변경을 반영하거나, 함수의 반환 값으로 포인터를 반환할 수 있습니다.

예시: 포인터를 함수 매개변수로 전달

#include <iostream>
using namespace std;

void changeValue(int* ptr) {
    *ptr = 100;  // 포인터가 가리키는 값 변경
}

int main() {
    int num = 10;
    cout << "변경 전 값: " << num << endl;  // 10 출력

    changeValue(&num);  // 포인터로 값을 변경
    cout << "변경 후 값: " << num << endl;  // 100 출력

    return 0;
}

설명:

  • changeValue 함수는 int 타입의 포인터를 매개변수로 받습니다. 함수 내부에서 *ptr을 통해 값을 변경합니다.
반응형