3

Can we free the array of primitive data types by using delete[] operator on void*. Ex.

char* charPtr = new char[100]
void* voidPtr = (void*)charPtr;
delete[] voidPtr;

Or it can be freed by using delete operator like

delete voidPtr

I do not expect it to call the destructor. I only expect it to free the memory whichever is allocated by new operator.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Ravindra12jan
  • 331
  • 2
  • 13

1 Answers1

12

No this is not valid, it is undefined behavior if we look at the C++ draft standard 5.3.5 Delete says (emphasis mine going forward):

The operand shall be of pointer to object type or of class type. If of class type, the operand is contextually implicitly converted (Clause 4) to a pointer to object type. The delete-expression’s result has type void.78

and footnote 78 says:

This implies that an object cannot be deleted using a pointer of type void* because void is not an object type.

On the other hand free does allow you to use a void* but the allocation had to have been via malloc, calloc or realloc.

Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
  • Why is it undefined when operator delete only takes `void*` as arguments? http://en.cppreference.com/w/cpp/memory/new/operator_delete and http://www.cplusplus.com/reference/new/operator%20delete[]/ It is also the case for allocators. Allocate and Deallocate functions take a `void*` and it works just fine. Can even open MSVC and Mingw headers and see.. – Brandon Feb 27 '14 at 14:58
  • 1
    @CantChooseUsernames A 'delete-expression' is not the same as the `operator delete`. In particular, the destructor for the relevant type is called prior to the operator call (which is why the operator only needs a `void*` - there's no object any more, only storage.) – molbdnilo Feb 27 '14 at 15:07
  • 1
    @CantChooseUsernames That is `operator delete` which is not the same as [delete expression](http://en.cppreference.com/w/cpp/language/delete). What makes this UB is that you are violating a *shall* constraint. – Shafik Yaghmour Feb 27 '14 at 15:08
  • @ShafikYaghmour I agree that the standard says not to use void*. But example which I am looking for, allocates the array of char which is primitive data type. Here I do not expect to call destrcutor of this char. And as pointed out by cantChooseusernames delete operator receives void*. So here the purpose of freeing the memory is achieved by calling delete[] voidPtr. – Ravindra12jan Feb 27 '14 at 15:19
  • @Ravindra12jan it is undefined, so the compiler is free to do anything even optimize out the code all together. So you can not rely on it. The only way that it would be ok is if the compiler documents that case as being supported but it still make it non-portable. – Shafik Yaghmour Feb 27 '14 at 15:27
  • @Ravindra12jan This post: [Finding Undefined Behavior Bugs by Finding Dead Code](http://blog.regehr.org/archives/970) shows an example of UB being optimized away. – Shafik Yaghmour Feb 27 '14 at 15:51
  • @Ravindra12jan without a better explanation of your goal I would have to guess this article [The many faces of operator new in C++](http://eli.thegreenplace.net/2011/02/17/the-many-faces-of-operator-new-in-c/) may provide some paths to what you are looking for. – Shafik Yaghmour Feb 28 '14 at 15:30