shared_ptr<void> t(new char[num]) means memory leak?

3.4k Views Asked by At
shared_ptr<void> t(new char[num])

means memory leak?

If so, what is the correct practice in this case.

should I use shared_array<> instead?

I'm editing the bytes pointed by 't' manually for later transfer in a TCP Stream.

5

There are 5 best solutions below

1
On BEST ANSWER

means memory leak?

No, it means undefined behavior. (Which could have any symptom, including memory leak.) The call to delete must match the call to new. Yours doesn't. You allocate with new[] but destroy with delete.

If so, what is the correct practice in this case. Should I use shared_array<> instead?

There are two easy choices. You can use shared_array:

shared_array<char> t(new char[num])
t[7] = 42;

Or, you could use a shared_ptr to a std::vector:

shared_ptr<std::vector<char> > t(new std::vector<char>(num))
(*t)[7] = 42;


EDIT: Thanks to @Dennis Zickefoose for gently pointing out an error in my thinking. Parts of my answer are rewritten.

5
On

As I see the void You mention in the Q is a typo, Since Calling delete on a void * is guaranteed Undefined Behavior by the Standard.

For another data type,

You will have to provide your custom deletor to the shared_ptr so you can call delete [].

Eg:

For example:

template<typename T>
struct Customdeleter
{
   void operator()(T* p)
   {
      delete [] p;
   }
};

And invoke as:

shared_ptr<char> sp(new char[num], Customdeleter<char>());

EDIT:
Since you clarified are using Boost in comments and not TR1(AFAIK TR1 doesn't have shared_array)

You can use shared_array:

shared_array<char> sp(new char[num])
2
On

You're calling delete on void* which is undefined behavior.

the reason I'm using a void* is because I'm allocating 'num' bytes for storage of different types of variables, like the first 4 bytes represent a double, next 2 bytes are short..

Use a struct or union then.

0
On

I don't know if C++11 has a shared_array, but Boost does — you should use that instead.

3
On

I think I see where you're coming from - you want void * pointers so you can later cast it to the final type you're serializing. But as others have pointed out, you can't delete a void* pointer, and neither can the code for shared_ptr.

Since you're allocating an array of char, that should be the type of smart pointer you use:

shared_array<char> t(new char[num]);

Casting the raw char pointer to another type shouldn't be any more of a problem than casting a void* pointer.