Is it safe to delete a void pointer?

2019-01-01 07:06发布

Suppose I have the following code:

void* my_alloc (size_t size)
{
   return new char [size];
}

void my_free (void* ptr)
{
   delete [] ptr;
}

Is this safe? Or must ptr be cast to char* prior to deletion?

13条回答
栀子花@的思念
2楼-- · 2019-01-01 07:29

There is hardly a reason to do this.

First of all, if you don't know the type of the data, and all you know is that it's void*, then you really should just be treating that data as a typeless blob of binary data (unsigned char*), and use malloc/free to deal with it. This is required sometimes for things like waveform data and the like, where you need to pass around void* pointers to C apis. That's fine.

If you do know the type of the data (ie it has a ctor/dtor), but for some reason you ended up with a void* pointer (for whatever reason you have) then you really should cast it back to the type you know it to be, and call delete on it.

查看更多
听够珍惜
3楼-- · 2019-01-01 07:35

The question makes no sense. Your confusion may be partly due to the sloppy language people often use with delete:

You use delete to destroy an object that was dynamically allocated. Do do so, you form a delete expression with a pointer to that object. You never "delete a pointer". What you really do is "delete an object which is identified by its address".

Now we see why the question makes no sense: A void pointer isn't the "address of an object". It's just an address, without any semantics. It may have come from the address of an actual object, but that information is lost, because it was encoded in the type of the original pointer. The only way to restore an object pointer is to cast the void pointer back to an object pointer (which requires the author to know what the pointer means). void itself is an incomplete type and thus never the type of an object, and a void pointer can never be used to identify an object. (Objects are identified jointly by their type and their address.)

查看更多
旧人旧事旧时光
4楼-- · 2019-01-01 07:38

Because char has no special destructor logic. THIS won't work.

class foo
{
   ~foo() { printf("huzza"); }
}

main()
{
   foo * myFoo = new foo();
   delete ((void*)foo);
}

The d'ctor won't get called.

查看更多
回忆,回不去的记忆
5楼-- · 2019-01-01 07:39

I have used void*, (aka unknown types) in my framework for while in code reflection and other feats of ambiguity, and so far, I have had no troubles (memory leak, access violations, etc.) from any compilers. Only warnings due to the operation being non-standard.

It perfectly makes sense to delete an unknown (void*). Just make sure the pointer follows these guidelines, or it may stop making sense:

1) The unknown pointer must not point to a type that has a trivial deconstructor, and so when casted as an unknown pointer it should NEVER BE DELETED. Only delete the unknown pointer AFTER casting it back into the ORIGINAL type.

2) Is the instance being referenced as an unknown pointer in stack bound or heap bound memory? If the unknown pointer references an instance on the stack, then it should NEVER BE DELETED!

3) Are you 100% positive the unknown pointer is a valid memory region? No, then it should NEVER BE DELTED!

In all, there is very little direct work that can be done using an unknown (void*) pointer type. However, indirectly, the void* is a great asset for C++ developers to rely on when data ambiguity is required.

查看更多
余生请多指教
6楼-- · 2019-01-01 07:42

Deleting a void pointer is dangerous because destructors will not be called on the value it actually points to. This can result in memory / resource leaks in your application.

查看更多
柔情千种
7楼-- · 2019-01-01 07:45

For the particular case of char.

char is an intrinsic type that does not have a special destructor. So the leaks arguments is a moot one.

sizeof(char) is usually one so there is no alignment argument either. In the case of rare platform where the sizeof(char) is not one, they allocate memory aligned enough for their char. So the alignment argument is also a moot one.

malloc/free would be faster on this case. But you forfeit std::bad_alloc and have to check the result of malloc. Calling the global new and delete operators might be better as it bypass the middle man.

查看更多
登录 后发表回答