Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Properly declaring smart pointers

Tags:

c++

I'm 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 involved here. I don't fully understand why the smart pointer semantics seem to run contrary to regular raw pointers.

like image 359
sircodesalot Avatar asked Mar 22 '23 14:03

sircodesalot


1 Answers

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

In your first, naked-array-new code, the second line doesn't make sense syntactically, since you cannot initialize an array with a pointer, and new returns a pointer.

The unique_ptr example is also wrong; the corrected version makes a lot more sense:

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

Spot the pattern?

The reason you need different template specializations is that you need to call either delete or delete[] on the pointer depending on how it was allocated, but you can't tell that just from looking at the raw pointer. (Also, the array version provides a handy []-operator.)

Nothing is stopping you from mixing unique_ptr<int> and new int[10], but it's a more or less subtle error that causes silent undefined behaviour (one more reason to never use new youreself and instead rely on make_unique!). By contrast, your first example is a simple syntactical error.

like image 142
Kerrek SB Avatar answered Apr 19 '23 21:04

Kerrek SB