Program Language/C++ 언어

07. C++ 배열과 포인터 - 포인터의 연산과 동적 할당 메모리

parkes811 2023. 8. 26. 16:38
  • 포인터 연산

- 포인터는 값을 증가시키거나 감소시키는 등의 제한된 연산만을 할 수 있습니다.

- C++의 포인터 연산의 규칙

  1. 포인터끼리의 덧셈, 곱셈, 나눗셈은 아무런 의미가 없습니다.
  2. 포인터끼리의 뺄셈은 두 포인터 사이의 상대적 거리를 나타냅니다.
  3. 포인터에 정수를 더하거나 뺄 수는 있지만, 실수와의 연산은 허용되지 않습니다.
  4. 포인터끼리 대입하거나 비교할 수 있습니다.

 


 

  • 타입별 포인터 연산

- C++의 포인터 연산에서 포인터 연산은 연산 후 각각의 포인터가 가리키고 있는 주소는 포인터의 타입에 따라 달라집니다.

- 그 증가 폭, 감소 폭은 포인터가 가리키는 변수의 타입의 크기와 같습니다. 

 


 

  • 포인터와 배열의 관계

- 포인터와 배열을 매우 긴밀한 관계를 맺고 있으며, 배열의 이름은 포인터와 같습니다.

- C++에서는 배열의 이름이 주소로 해석되며, 해당 배열의 첫 번째 요소의 주소와 같습니다.

int arr[3] = {10, 20, 30}; // 배열 선언
int* ptr_arr = arr; // 포인터에 배열의 이름을 대입함.

cout << "배열의 이름을 이용하여 배열 요소에 접근 : " << arr[0] << ", " << arr[1] << ", " << arr[2] << endl;
cout << " 포인터를 이용하여 배열 요소에 접근 : "

cout  << ptr_arr[0] << ", " << ptr_arr[1] << ", " << ptr_arr[2] << endl;
	 << "배열의 이름을 이용한 배열의 크기 계산 : " << sizeof(arr) << endl;

cout << " 포인터를 이용한 배열의 크기 계산 : " << sizeof(ptr_arr);

 


 

  • 배열의 포인터 연산
int arr[3] = {10, 20, 30}; // 배열 선언

cout << " 배열의 이름을 이용하여 배열 요소에 접근 : " << arr[0] << ", " << arr[1] << ", " << arr[2] << endl;
cout << "배열의 이름으로 포인터 연산을 해 배열 요소에 접근 : "
    << *(arr+0) << ", " << *(arr+1) << ", " << *(arr+2);

 

- 배열의 이름을 포인터 처럼 사용할 수 있습니다. 

- 배열의 이름으로 포인터 연산을 진행하여 배열에 요소에 접근합니다.

 


 

  • 메모리의 동적 할당 (Dynamic Allocation)

- 데이터 영역과 스택 영역에 할당되는 메모리 크기는 Compile Time에 미리 결정됩니다. 하지만 힙 영역의 크기는 프로그램이 실행되는 도중인 Run Time에 사용자가 직접 결정하게 됩니다.

- 이렇게 Run Time에 메모리를 할당 받는 것을 메모리의 동적 할당이라고 합니다.

- 포인터의 가장 큰 목적은 Run Time에 이름 없는 메모리를 할당받아 포인터에 할당하여, 할당 받은 메모리에 접근 하는 것입니다.

 

  • new 연산자를 활용해 메모리의 동적 할당 받기
타입* 포인터이름 = new 타입;

- 첫 번째 타입은 데이터에 맞는 포인터를 선언하기 위해, 두 번째 new 뒤에 타입은 메모리의 종류를 지정하기 위해 사용합니다.

- new 연산자는 Free Store라고 불리는 메모리 공간(= Memory Pool)에 객체를 위한 메모리를 할당받습니다.

- new 연산자를 통해 할당받은 메모리는 따로 이름이 없으므로 해당 포인터로만 접근할 수 있게 됩니다.

 


 

  • delete 연산자를 활용한 동적 메모리 해제
delete 포인터이름;

- delete연산자는 C언어에서 사용하는 free()함수와 마찬가지로 동적으로 할당받는 메모리를 운영체제로 반환하는 연산자입니다.

- delete 연산자는 반드시 new 연산자를 통해 할당된 메모리를 해제할 때에만 사용해야 합니다.