I am trying to use the C++11 to support the smart pointer, but I find there is no shard_array in <memory>, so I try to use it in this way, and I know this maybe WRONG:

shared_ptr<int> sp(new int[10]);

Then run it, it coredumped as I guessed:

<br />
$ smart_ptr/Test_shared_array<br />
Destructing a Foo with x=0<br />
*** Error in `smart_ptr/Test_shared_array': munmap_chunk(): invalid pointer: 0x0000000001d58018 ***<br />
[1]    14128 abort (core dumped)  smart_ptr/Test_shared_array<br />


Use GDB to see more information:

<br />
(gdb) run<br />
Starting program: /home/nasacj/projects/woodycxx/smart_ptr/Test_shared_array<br />
Destructing a Foo with x=0<br />
*** Error in `/home/nasacj/projects/woodycxx/smart_ptr/Test_shared_array': munmap_chunk(): invalid pointer: 0x0000000000603018 ***</p>
<p>Program received signal SIGABRT, Aborted.<br />
0x00007ffff7530cc9 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56<br />
56	../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.<br />
(gdb) bt<br />
#0  0x00007ffff7530cc9 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56<br />
#1  0x00007ffff75340d8 in __GI_abort () at abort.c:89<br />
#2  0x00007ffff756df24 in __libc_message (do_abort=do_abort@entry=1, fmt=fmt@entry=0x7ffff767c6c8 &quot;*** Error in `%s': %s: 0x%s ***\n&quot;) at ../sysdeps/posix/libc_fatal.c:175<br />
#3  0x00007ffff7578c87 in malloc_printerr (action=&lt;optimized out&gt;, str=0x7ffff767ca48 &quot;munmap_chunk(): invalid pointer&quot;, ptr=&lt;optimized out&gt;) at malloc.c:4996<br />
#4  0x0000000000400d9f in _M_release (this=0x603050) at /usr/include/c++/4.8/bits/shared_ptr_base.h:144<br />
#5  ~__shared_count (this=&lt;optimized out&gt;, __in_chrg=&lt;optimized out&gt;) at /usr/include/c++/4.8/bits/shared_ptr_base.h:546<br />
#6  ~__shared_ptr (this=&lt;optimized out&gt;, __in_chrg=&lt;optimized out&gt;) at /usr/include/c++/4.8/bits/shared_ptr_base.h:781<br />
#7  ~shared_ptr (this=&lt;optimized out&gt;, __in_chrg=&lt;optimized out&gt;) at /usr/include/c++/4.8/bits/shared_ptr.h:93<br />
#8  test () at Test_shared_array.cpp:30<br />
#9  0x0000000000400bc9 in main () at Test_shared_array.cpp:36<br />
(gdb) quit<br />


Then I realize that in Boost, user should provide a deleter to shared_ptr:

Then I find this in stackoverflow:

By default, shared_ptr will call delete on the managed object when no more references remain to it. However, when you allocate using new[] you need to call delete[], and not delete, to free the resource.

In order to correctly use shared_ptr with an array, you must supply a custom deleter.

<br />
template&lt; typename T &gt;<br />
struct array_deleter<br />
{<br />
  void operator ()( T const * p)<br />
  {<br />
    delete[] p;<br />
  }<br />
};<br />

Create the shared_ptr as follows

std::shared_ptr<int> sp( new int[10], array_deleter<int>() );

Now shared_ptr will correctly call delete[] when destroying the managed object.


With C++11, you can also use a lambda instead of the functor.

std::shared_ptr<int> sp( new int[10], []( int *p ) { delete[] p; } );


Also, unless you actually need to share the managed object, a unique_ptr is better suited for this task, since it has a partial specialization for array types.

std::unique_ptr<int[]> up( new int[10] ); // this will correctly call delete[]


Now there come the shared array STD version in practice:

<br />
//#include &quot;shared_array.h&quot;<br />
#include &lt;memory&gt;<br />
#include &lt;iostream&gt;</p>
<p>using namespace std;</p>
<p>struct Foo<br />
{<br />
    Foo() : x(0) {}<br />
	Foo( int _x ) : x(_x) {}<br />
	~Foo() { std::cout &lt;&lt; &quot;Destructing a Foo with x=&quot; &lt;&lt; x &lt;&lt; &quot;\n&quot;; }<br />
	int x;<br />
	/* ... */<br />
};</p>
<p>template&lt; typename T &gt;<br />
struct array_deleter<br />
{<br />
  void operator ()( T const * p)<br />
  {<br />
    delete[] p;<br />
  }<br />
};</p>
<p>//typedef woodycxx::smart_prt::shared_array&lt;Foo&gt; FooArray;<br />
typedef shared_ptr&lt;Foo&gt; FooArray;</p>
<p>void test()<br />
{<br />
	FooArray(new Foo[10], array_deleter&lt;Foo&gt;());<br />
}</p>
<p>int main()<br />
{<br />
	test();<br />
	return 0;<br />
}<br />

The Output:

<br />
$ ./Test_shared_array<br />
Destructing a Foo with x=0<br />
Destructing a Foo with x=0<br />
Destructing a Foo with x=0<br />
Destructing a Foo with x=0<br />
Destructing a Foo with x=0<br />
Destructing a Foo with x=0<br />
Destructing a Foo with x=0<br />
Destructing a Foo with x=0<br />
Destructing a Foo with x=0<br />
Destructing a Foo with x=0<br />

Smart Pointer Programming Techniques

Using incomplete classes for implementation hiding
The “Pimpl” idiom
Using abstract classes for implementation hiding
Preventing delete px.get()
Using a shared_ptr to hold a pointer to an array
Encapsulating allocation details, wrapping factory functions
Using a shared_ptr to hold a pointer to a statically allocated object
Using a shared_ptr to hold a pointer to a COM object
Using a shared_ptr to hold a pointer to an object with an embedded reference count
Using a shared_ptr to hold another shared ownership smart pointer
Obtaining a shared_ptr from a raw pointer
Obtaining a shared_ptr (weak_ptr) to this in a constructor
Obtaining a shared_ptr to this
Using shared_ptr as a smart counted handle
Using shared_ptr to execute code on block exit
Using shared_ptr<void> to hold an arbitrary object
Associating arbitrary data with heterogeneous shared_ptr instances
Using shared_ptr as a CopyConstructible mutex lock
Using shared_ptr to wrap member function calls
Delayed deallocation
Weak pointers to objects not managed by a shared_ptr