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
Robᵩ 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
Alok Save 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
Pubby 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
Paul Manta On

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

3
Mark Ransom 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.