0

This simple code can be compiled.

unique_ptr<list<int>> map1(new list<int>[10]);

But it causes seg falut when running.

malloc: * error for object 0x7fe02a4032e8: pointer being freed was not allocated * set a breakpoint in malloc_error_break to debug

However this code successfully ran.

unique_ptr<int> map2(new int[10]);

Why array of list can not be made using unique_ptr?

Thanks in advance.

3 Answers3

4

You need to use unique_ptr version for dynamically allocated arrays:

std::unique_ptr<std::list<int>[]> map1(new std::list<int>[10]);
                              ^^ ~~~~~ !

See here: http://en.cppreference.com/w/cpp/memory/unique_ptr :

template <
    class T,
    class Deleter
> class unique_ptr<T[], Deleter>;

You can also use std::make_unique (as suggested in comments) with which you would get compile error instead of UB, as its interface protects against it:

std::unique_ptr<std::list<int>[]> up1 = std::make_unique<std::list<int>[]>(10);
auto up2 = std::make_unique<std::list<int>[]>(10);

[edit]

However this code successfully ran.

unique_ptr map2(new int[10]);

Its still Undefined Behaviour in above code, it may work or may cause seg fault. unique_ptr as above accepts any pointer but will always call delete during destructon. Calling delete on pointer which points to dynamically allocated array is UB. Thats why you need to call delete[] and this is what does unique_ptr for dynamically allocated arrays.

marcinj
  • 44,446
  • 9
  • 70
  • 91
1

A A list<int> and a list<int>[10] are two different types. When you have a

unique_ptr<list<int>>

You are telling unique_ptr that it is going to point to a list<int>. When the unique_ptr goes out of scope it is going to call delete to delete the underlying pointer. Unfortunetly you initialize it with

new list<int>[10]

which needs to be deleted with delete [] not delete. This is the same for

unique_ptr<int> map2(new int[10]);

Why does the first version fail and the second does not?: Undefined behavior.

It is undefined behavior to call delete on something that has been new[]ed

So if you are going to use new[] in the constructor you need to use type[] for the type of the unique_ptr

NathanOliver
  • 150,499
  • 26
  • 240
  • 331
0

What you need is:

std::unique_ptr<std::list<int>[]> map1(new std::list<int>[10]);

Live Demo

101010
  • 39,010
  • 10
  • 84
  • 149