Skip to main content
gamedev.net
🔒 Locked

Deleting void pointer arrays

Started by Coldon 16 replies 2.1k views
Original Post
Coldon
Coldon
Okay so I'm beyond confused at this point, everywhere i search people say that deleting void pointer arrays is undefined and the memory wont be deallocated, but in my tests deleting void pointer arrays frees the memory just fine both with the VS 2005 and VS 2008 c++ compiler.

I cant find a single official reference that says that deleting void pointers is problematic, but almost every single forums post opinion on the matter claims that deleting a void pointer array wont work.

//allocate ~77MBvoid* pTest = new double[10000000];delete[] pTest;


this code allocates and deallocates the memory just fine on my test machines so like I said I'm confused. Any comments?
"In theory, theory and practice are the same. In Practice, they never are."
My Technical Blog : http://www.takinginitiative.net/
ApochPiQ
ApochPiQ
"Undefined" doesn't mean "it won't work." "Undefined" means just that - it might do what you expect, it might crash, it might summon demon monkeys from your DVD drive, you never know.

Try it with a class that has a nontrivial destructor, for instance.
Burnhard
Burnhard

What's wrong with:

{
std::vector myVector;

myVector.reserve(10000000);
}

Tada! myVector has been deleted.

Rattenhirn
Rattenhirn
Quote:
Original post by Coldonthis code allocates and deallocates the memory just fine on my test machines so like I said I'm confused. Any comments?


For non POD types, new and delete does more than allocate and deallocate memory. It also calls constructors and destructors.

The proper calling of destructors may not work if you delete through a void pointer or mix up delete with delete[].


Rattenhirn
Rattenhirn
Quote:
Original post by Burnhard

What's wrong with:

{
std::vector myVector;

myVector.reserve(10000000);
}

Tada! myVector has been deleted.


Nitpick:
myVector.resize(10000000); // would fit the bill exactly.
Possibly even better:
myVector.resize(10000000, 0.0); // the right size + initialised to 0.0! Yay!
Plerion
Plerion
Quote:
Original post by Coldon
I cant find a single official reference [...]


Thats whats called undefined behaviour. Its up to the OS, the compiler, ... what to do in that situation.

diablos_blade
diablos_blade
I'm just going to come straight out and ask, why are you using void pointers?
Especially deleting them as void pointers, when all type information is probably lost.
There are really very few occasions you should even consider using one.
Normally I go with the "If it works, who cares?" approach when learning/experimenting, because after a bit of reasearch and experience you'll be able to implement something better next time around. But void pointers are one of those things I have to question when I see them.

This was hinted at by others in the thread, but I thought I'd explicitly ask.
Coldon
Coldon
well to further nitpick, to complete free all the memory allocated to a vector you could also do something like:

vector<type>().swap(myVector);


I'm not actually using a void* but rather a unsigned char* in my case, i reading in a lot of values from an XML file and their type can vary from bool, int, float, etc... so I am allocating a big chunk of memory than can store them all in and then indexing the generic data array according to their type bytewidth.

my OCD was freaking out at having an unsigned char array for storing unknown data types, so i was looking at making it a void* array just for code neatness. I did some searching and couldnt find an answer so i thought it was a curious question.

Its obvious that a delete on complex objects cast to void* wont call their destructors and I was only planning on using it for the base types. So basically I guess deleting void* array for basic types is semi-safe :p
"In theory, theory and practice are the same. In Practice, they never are."
My Technical Blog : http://www.takinginitiative.net/
SiCrane
SiCrane
Quote:
Original post by Rattenhirn
myVector.resize(10000000); // would fit the bill exactly.
Possibly even better:
myVector.resize(10000000, 0.0); // the right size + initialised to 0.0!

These two statements are equivalent.
Rattenhirn
Rattenhirn
Quote:
Original post by Coldon
my OCD was freaking out at having an unsigned char array for storing unknown data types, so i was looking at making it a void* array just for code neatness. I did some searching and couldnt find an answer so i thought it was a curious question.


Firstly, maybe you should look for treatment for your OCD. Secondly, using void* instead of unsigned char* doesn't make any code any neater.

It actually does the opposite. Anyone who sees the delete[] on the void ptr will think something fishy is going on here and will have to go through the trouble of locating where this memory came from. Some (most?) compilers will even issue warnings.

If you want to be perfectly clear that you've allocated a bunch of generic memory, instead of a lot of, er, characters, use a typedef.
typedef unsigned char my_generic_memory_t;[...]my_generic_memory_t* ptr = new my_generic_memory_type[10000000];[...]delete[] ptr;


No warnings, no undefined behavior, no confusion with char as in character.
Rattenhirn
Rattenhirn
Quote:
Original post by SiCrane
Quote:
Original post by Rattenhirn
myVector.resize(10000000); // would fit the bill exactly.
Possibly even better:
myVector.resize(10000000, 0.0); // the right size + initialised to 0.0!

These two statements are equivalent.


That's right. I should have picked another value! ;)
Nitage
Nitage
A void* is almost always the incorrect thing to use. In your case, you're allocating 10m bytes - so unsigned char is a perfectly good type as it's equivilent to byte (on non-esoteric platforms at least).
Coldon
Coldon
haha, guess I've been working with the DX SDK for way too long where you come across void* quite a lot.

like I said I used an unsigned char since it is (as you said) in most cases 1 byte wide. My question was more of an academic one. I'm surprised my compiler didn't throw up a warning or something.
"In theory, theory and practice are the same. In Practice, they never are."
My Technical Blog : http://www.takinginitiative.net/
SiCrane
SiCrane
It doesn't give you a warning because you can use operator new and operator new[] to allocate an untyped block of memory and they return a void * to that block. And, of course, you would use the corresponding delete or delete[] to return that memory to the system.
  void * ptr = operator new[](5);  delete [] ptr;
Antheus
Antheus
void* pTest = new double[10000000];delete[] (double*)pTest;


Of course, it's up to user to make sure types are correct
Plerion
Plerion
Quote:
Original post by Coldon
[...]unsigned char since it is (as you said) in most cases 1 byte wide. [...]


It is 1 byte on EVERY platform that is according to the C-standard. char must be 1 byte wide (while the number of bits in a byte is not fixed).

ApochPiQ
ApochPiQ
Quote:
Original post by Plerion
Quote:
Original post by Coldon
[...]unsigned char since it is (as you said) in most cases 1 byte wide. [...]


It is 1 byte on EVERY platform that is according to the C-standard. char must be 1 byte wide (while the number of bits in a byte is not fixed).


While sizeof(char) == 1 by definition, this does not mean that a char is an octet (8-bit byte) or any other platform-dependent definition of byte. According to the C standard, a char must be able to hold at least 255 values and must at least be able to contain all the default character set values of a platform. Typically this means 8 bits worth of data, but not always - there are platforms with 16-bit characters, for instance. That is, a platform's byte (smallest addressable unit) may be smaller than a char in some circumstances.

This is just semantic nitpicking, really, but it's important to keep clarity of terminology [smile]
Hodgman
Hodgman
Quote:
Original post by Coldon
I cant find a single official reference...
Have you checked the language specification?

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.