전제 조건: C++의 포인터
포인터는 힙 메모리와 같이 프로그램 외부의 리소스에 액세스하는 데 사용됩니다. 따라서 힙 메모리에 액세스하기 위해(힙 메모리 내부에 무언가가 생성된 경우) 포인터가 사용됩니다. 외부 리소스에 액세스할 때 우리는 리소스의 복사본을 사용합니다. 변경사항이 있으면 복사된 버전에서 변경하면 됩니다. 그러나 리소스에 대한 포인터를 사용하면 원래 리소스를 변경할 수 있습니다.
일반 포인터 문제
C++의 일반 포인터와 관련된 일부 문제는 다음과 같습니다.
- 메모리 누수: 이는 프로그램에 의해 메모리가 반복적으로 할당되었지만 결코 해제되지 않을 때 발생합니다. 이로 인해 과도한 메모리 소비가 발생하고 결국 시스템 충돌이 발생합니다. 댕글링 포인터(Dangling Pointer): 댕글링 포인터는 포인터 값을 수정하지 않고 객체가 메모리에서 할당 해제될 때 발생하는 포인터입니다. 와일드 포인터: 와일드 포인터는 선언되고 메모리가 할당되는 포인터이지만 포인터는 유효한 개체나 주소를 가리키도록 초기화되지 않습니다. 데이터 불일치: 데이터 불일치는 일부 데이터가 메모리에 저장되어 있지만 일관된 방식으로 업데이트되지 않을 때 발생합니다. 버퍼 오버플로: 포인터가 할당된 메모리 블록 외부의 메모리 주소에 데이터를 쓰는 데 사용되는 경우입니다. 이로 인해 악의적인 공격자가 악용할 수 있는 데이터가 손상됩니다.
예:
C++
// C++ program to demonstrate working of a Pointers> #include> using> namespace> std;> class> Rectangle {> private>:> >int> length;> >int> breadth;> };> void> fun()> {> >// By taking a pointer p and> >// dynamically creating object> >// of class rectangle> >Rectangle* p =>new> Rectangle();> }> int> main()> {> >// Infinite Loop> >while> (1) {> >fun();> >}> }> |
>
>
산출
Memory limit exceeded>
설명: 기능 중 재미있는 , 이는 다음을 가리키는 포인터를 생성합니다. 직사각형 물체. 그 물체 직사각형 두 개의 정수를 포함하고, 길이, 그리고 폭 . 기능을 할 때 재미있는 종료되면 p는 지역 변수이므로 소멸됩니다. 하지만 사용하는 것을 잊어버렸기 때문에 소비된 메모리는 할당 해제되지 않습니다. p 삭제; 기능이 끝나면. 즉, 다른 리소스에서 메모리를 자유롭게 사용할 수 없습니다. 하지만 더 이상 변수가 필요하지 않고 메모리가 필요합니다.
기능상, 기본 , 재미있는 무한 루프에서 호출됩니다. 즉, 계속해서 생성된다는 뜻입니다. 피 . 점점 더 많은 메모리를 할당하지만 할당을 취소하지 않았기 때문에 해제되지는 않습니다. 낭비된 메모리는 다시 사용할 수 없습니다. 메모리 누수입니다. 전체 더미 이러한 이유로 메모리가 쓸모 없게 될 수 있습니다.
스마트 포인터
우리가 무의식적으로 포인터 할당을 해제하지 않으면 프로그램 충돌로 이어질 수 있는 메모리 누수가 발생한다는 것을 알고 있습니다. Java, C#의 언어 가비지 수집 메커니즘 다시 사용할 수 있도록 사용되지 않은 메모리를 현명하게 할당 해제합니다. 프로그래머는 메모리 누수에 대해 걱정할 필요가 없습니다. C++에서는 다음과 같은 자체 메커니즘을 제공합니다. 스마트 포인터 . 객체가 파괴되면 메모리도 해제됩니다. 따라서 스마트 포인터가 처리하므로 삭제할 필요가 없습니다.
ㅏ 스마트 포인터 다음과 같은 연산자가 있는 포인터에 대한 래퍼 클래스입니다. * 그리고 -> 과부하. 스마트 포인터 클래스의 객체는 일반 포인터처럼 보입니다. 하지만 달리 일반 포인터, 파괴된 객체 메모리를 할당 해제하고 해제할 수 있습니다.
아이디어는 포인터로 수업을 듣는 것입니다. 파괴자, 그리고 다음과 같은 오버로드된 연산자 * 그리고 -> . 객체가 범위를 벗어나면 소멸자가 자동으로 호출되므로 동적으로 할당된 메모리는 자동으로 삭제됩니다(또는 참조 횟수가 감소될 수 있습니다).
예:
C++
// C++ program to demonstrate the working of Smart Pointer> #include> using> namespace> std;> class> SmartPtr {> >int>* ptr;>// Actual pointer> public>:> >// Constructor: Refer> >// techcodeview.com for use of> >// explicit keyword> >explicit> SmartPtr(>int>* p = NULL) { ptr = p; }> >// Destructor> >~SmartPtr() {>delete> (ptr); }> >// Overloading dereferencing operator> >int>& operator*() {>return> *ptr; }> };> int> main()> {> >SmartPtr ptr(>new> int>());> >*ptr = 20;> >cout << *ptr;> >// We don't need to call delete ptr: when the object> >// ptr goes out of scope, the destructor for it is> >// automatically called and destructor does delete ptr.> >return> 0;> }> |
>
>산출
20>
포인터와 스마트 포인터의 차이점
| 바늘 | 스마트 포인터 |
|---|---|
| 포인터는 메모리 주소와 해당 메모리 위치에 대한 데이터 유형 정보를 유지하는 변수입니다. 포인터는 메모리의 무언가를 가리키는 변수입니다. | 포인터 래핑 스택 할당 객체입니다. 스마트 포인터는 간단히 말해서 포인터 또는 범위가 지정된 포인터를 래핑하는 클래스입니다. |
| 범위를 벗어나도 어떤 형태로든 파괴되지 않습니다. | 범위를 벗어나면 스스로 파괴됩니다. |
| 포인터는 다른 기능을 지원하지 않기 때문에 효율적이지 않습니다. | 스마트 포인터에는 추가 메모리 관리 기능이 있으므로 더 효율적입니다. |
| 그들은 매우 노동 중심적이고 수동적입니다. | 본질적으로 자동/사전 프로그래밍되어 있습니다. |
메모: 이것은 다음에서만 작동합니다. 정수 . 그러면 모든 개체에 대해 스마트 포인터를 만들어야 합니까? 아니요 , 해결책이 있습니다 주형 . 아래 코드에서 볼 수 있듯이 티 어떤 유형이든 가능합니다.
자바에서 배열 정렬
예:
C++
// C++ program to demonstrate the working of Template and> // overcome the issues which we are having with pointers> #include> using> namespace> std;> // A generic smart pointer class> template> <>class> T>>class> SmartPtr {> >T* ptr;>// Actual pointer> public>:> >// Constructor> >explicit> SmartPtr(T* p = NULL) { ptr = p; }> >// Destructor> >~SmartPtr() {>delete> (ptr); }> >// Overloading dereferencing operator> >T& operator*() {>return> *ptr; }> >// Overloading arrow operator so that> >// members of T can be accessed> >// like a pointer (useful if T represents> >// a class or struct or union type)> >T* operator->() {>return> ptr; }> };> int> main()> {> >SmartPtr<>int>>ptr(>new> int>());> >*ptr = 20;> >cout << *ptr;> >return> 0;> }> |
>
>산출
20>
메모: 스마트 포인터는 파일 핸들이나 네트워크 소켓과 같은 리소스 관리에도 유용합니다.
스마트 포인터의 유형
C++ 라이브러리는 다음 유형의 스마트 포인터 구현을 제공합니다.
- auto_ptr
- 고유_ptr
- shared_ptr
- 약한_ptr
auto_ptr
auto_ptr을 사용하면 새 표현식에서 얻은 개체를 관리하고 auto_ptr 자체가 삭제될 때 해당 개체를 삭제할 수 있습니다. auto_ptr을 통해 개체를 설명하면 단일 할당 개체에 대한 포인터가 저장됩니다.
메모: 이 클래스 템플릿은 C++11부터 더 이상 사용되지 않습니다. Unique_ptr은 기능은 유사하지만 보안이 향상된 새로운 기능입니다.
고유_ptr
고유_ptr 하나의 포인터만 저장합니다. 포인터에서 현재 개체를 제거하여 다른 개체를 할당할 수 있습니다.
예:
C++
부락 오즈시비트
// C++ program to demonstrate the working of unique_ptr> // Here we are showing the unique_pointer is pointing to P1.> // But, then we remove P1 and assign P2 so the pointer now> // points to P2.> #include> using> namespace> std;> // Dynamic Memory management library> #include> class> Rectangle {> >int> length;> >int> breadth;> public>:> >Rectangle(>int> l,>int> b)> >{> >length = l;> >breadth = b;> >}> >int> area() {>return> length * breadth; }> };> int> main()> {> // --/ Smart Pointer> >unique_ptr P1(>new> Rectangle(10, 5));> >cout // This'll print 50 // unique_ptr P2(P1); unique_ptr P2; P2 = move(P1); // This'll print 50 cout // cout return 0; }> |
>
>산출
50 50>
shared_ptr
사용하여 shared_ptr 두 개 이상의 포인터가 한 번에 하나의 개체를 가리킬 수 있으며 참조 카운터 사용하여 use_count() 방법.

C++
// C++ program to demonstrate the working of shared_ptr> // Here both smart pointer P1 and P2 are pointing to the> // object Addition to which they both maintain a reference> // of the object> #include> using> namespace> std;> // Dynamic Memory management library> #include> class> Rectangle {> >int> length;> >int> breadth;> public>:> >Rectangle(>int> l,>int> b)> >{> >length = l;> >breadth = b;> >}> >int> area() {>return> length * breadth; }> };> int> main()> {> >//---/ Smart Pointer> >shared_ptr P1(>new> Rectangle(10, 5));> >// This'll print 50> >cout shared_ptr P2; P2 = P1; // This'll print 50 cout // This'll now not give an error, cout // This'll also print 50 now // This'll print 2 as Reference Counter is 2 cout << P1.use_count() << endl; return 0; }> |
>
>산출
50 50 50 2>
약한_ptr
Weak_ptr은 객체에 대한 비소유 참조를 보유하는 스마트 포인터입니다. 유지하지 않는다는 점을 제외하면 shared_ptr과 훨씬 더 유사합니다. 참조 카운터 . 이 경우 포인터는 개체에 대한 거점을 갖지 않습니다. 그 이유는 포인터가 객체를 보유하고 다른 객체를 요청한다고 가정하면 포인터가 객체를 형성할 수 있기 때문입니다. 이중 자물쇠.

C++
// C++ program to demonstrate the working of weak_ptr> // Here both smart pointer P1 and P2 are pointing to the> // object Addition to which they both does not maintain> // a reference of the object> #include> using> namespace> std;> // Dynamic Memory management library> #include> class> Rectangle {> >int> length;> >int> breadth;> public>:> >Rectangle(>int> l,>int> b)> >{> >length = l;> >breadth = b;> >}> >int> area() {>return> length * breadth; }> };> int> main()> {> >//---/ Smart Pointer> >shared_ptr P1(>new> Rectangle(10, 5));> > >// create weak ptr> >weak_ptr P2 (P1);> > >// This'll print 50> >cout // This'll print 1 as Reference Counter is 1 cout << P1.use_count() << endl; return 0; }> |
>
>산출
50 1>
C++ 라이브러리는 auto_ptr, Unique_ptr, shared_ptr 및 Weak_ptr 형식의 스마트 포인터 구현을 제공합니다.