The correct declaration of smart pointers

I am a little confused by this:

int *pointer = new int[100]; // Yes int array [] = new int[100]; // No 

But:

 unique_ptr<int*> pointer { new int[100] }; // No unique_ptr<int[]> array { new int[100] }; // Yes 

can someone explain the general principle that is present here. I don’t quite understand why the semantics of smart pointers seem to work as opposed to regular source pointers.

+4
source share
2 answers

Smart pointers are library code, so they work the way they do, because someone created them that way.

In the first, new voice array, the second line does not make sense syntactically, since you cannot initialize the array with a pointer, and new returns a pointer.

The unique_ptr example unique_ptr also unique_ptr ; The fixed version makes more sense:

 // +--------------+------------ pointer to int // VV std::unique_ptr<int> p { new int; } std::unique_ptr<int[]> p { new int[10]; } // ^ ^ // +----------------+---------- pointer to first element // of an array of int 

Define a pattern?

The reason you need different specialized specializations is because you need to call either delete or delete[] in the pointer depending on how it was allocated, but you cannot say that you just looked at the raw pointer. (In addition, the array version provides a convenient [] operator.)

Nothing prevents you from mixing unique_ptr<int> and new int[10] , but it is a more or less subtle error that causes undefined to work quietly (another reason to never use new youreself and rely on make_unique !). On the contrary, your first example is a simple syntax error.

+5
source

I agree 100% with Kerrek SB's answer. Here, I would just like to add another powerful feature. You can also define your own deleter class

  auto deleter= [](int* ptr){delete[] ptr;}; std::unique_ptr<int, decltype(deleter)> ptr4(new int[100], deleter); 

It looks complicated, but it can be very useful if, for example, you need to call some C library, which requires allocation of a heap of C structs

Case Study: GSL GNU Science Library The integration procedure requires the allocation of a structure called "gsl_integration_workspace". In this case, you can use the following code to ensure the security of the code.

  auto deleter= [](gsl_integration_workspace* ptr) { gsl_integration_workspace_free(ptr); }; std::unique_ptr<gsl_integration_workspace, decltype(deleter)> ptr4 ( gsl_integration_workspace_alloc (2000), deleter); 

As Kerrek SB said, since smart pointers are library code, they provide more powerful ways to manage memory than source pointers.

+2
source

Source: https://habr.com/ru/post/1499885/


All Articles