#156686 - tepples - Mon May 12, 2008 8:24 pm
There is a difference between delete and delete[] because there is a difference between new T and new T[count]: the C++ language support library needs to know how many destructors to call. But why is there a difference between new T and new T[1]?
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#156696 - Bania - Mon May 12, 2008 9:17 pm
This is array, but only one with one element. I don't know how it looks in memory (difference between array and normal var). That operator new[count] is overloaded for array and there is nonsens if you wanna to make a array with one element.
_________________
Sorry for my level of English :)
Last edited by Bania on Fri Jun 13, 2008 2:46 pm; edited 2 times in total
#156697 - keldon - Mon May 12, 2008 9:25 pm
Well technically it's still an array by design; just consider the following (and passing 1)...
Code: |
My_Class* create_array ( int size )
{
return new My_Class[size];
} |
... so although the object occupies the same user memory as a pointer that is [just] allocating a new My_Class, the memory manager should not handle it like a new My_Class as your design expects arrays.
#156699 - kusma - Mon May 12, 2008 10:07 pm
tepples wrote: |
the C++ language support library needs to know how many destructors to call. |
But how does it know that? "delete[] array;" doesn't include any info on the allocation itself - so I guess the an extra integer must be allocated at the beginning of the array, storing the size of the array. Or something of that sort, perhaps? Just a loose theory, though.
edit: ...and it seems that the c++ faq lite agrees with me.
#156721 - silent_code - Tue May 13, 2008 9:16 am
i guess some sort of heap header structure would store the size. ;^)
_________________
July 5th 08: "Volumetric Shadow Demo" 1.6.0 (final) source released
June 5th 08: "Zombie NDS" WIP released!
It's all on my page, just click WWW below.
#156729 - simonjhall - Tue May 13, 2008 12:25 pm
Alright, similar problem to this delete/delete[] thing.
I've got this memory allocator that is basically used like this:
Code: |
MyClass *xyz = new(my_allocator(10 * sizeof(MyClass))) MyClass[10]; |
This works hunky-dorey on GCC. The problem is with Visual C++ (2005).
Let's say my_allocator returns a pointer to 0x1000 and the size of my class is sixteen bytes, ie I've asked to allocate 160 bytes. This means that the pointer returned will be valid from 0x1000 to 0x10a0.
However when I use VC, the address that gets assigned to xyz is 0x1004. The lower four bytes contain the number of elements I've allocated.
When it comes to deleting the data I would do this:
Code: |
for (int count = 0; count < 10; count+)
xyz->~MyClass();
my_deallocator(xyz); |
Again, this works fine with GCC.
But with VC xyz points to a piece of data within the buffer I've allocated, so I end up freeing 0x1004 rather than 0x1000. To top it off, if I access the last element in the array (element 9) I'll be reading/writing into memory that I don't own.
What am I doing wrong? What should I be doing? I'm not mega-cool with C++ as I'm a C programmer instead. Go easy.
_________________
Big thanks to everyone who donated for Quake2
#156738 - silent_code - Tue May 13, 2008 2:12 pm
@ simon:
i haven't seen such an "allocation scheme" (i really mean the way you use these elements), but then, what *have* i seen so far?
that is indeed something interesting. maybe investigating some ASM output from the compiler would help? i have no idea.
this would be one of those cases, that i wish i had metter debugging tools at hand. :^C
good luck finding out what makes the allocation drift. ;^)
_________________
July 5th 08: "Volumetric Shadow Demo" 1.6.0 (final) source released
June 5th 08: "Zombie NDS" WIP released!
It's all on my page, just click WWW below.
#156741 - sniper - Tue May 13, 2008 3:15 pm
delete[] xyz is only an information that an array was allocated e.g. new xyz[..].
Most newer C++ compilers doesn't need this info anymore.
so delete xyz and delete [] xyz has the same result.
Also you do not need to add the number of allocated elements like delete [10] xyz <- this is wrong.
#156756 - elyk1212 - Tue May 13, 2008 7:29 pm
Kusma, Have you checked out C++ FAQ Lite? It is one of the best free resources for C++.
This FAQ referrers to your follow up question *almost* directly:
http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.14
Quote: |
Most newer C++ compilers doesn't need this info anymore.
|
I would still say it's a pretty good idea to use though (delete []). This will help with object deconstruction in the case of an array of objects created on the heap. But anyhow, check out the C++ FAQ for more details. Really handy! :)
#156757 - sajiimori - Tue May 13, 2008 7:41 pm
simonjhall,
In general, you shouldn't implement any versions of 'new' that require additional information to be provided when 'delete' is called: all 'delete' should have to know is the pointer and whether it's an array.
With that restriction in mind, you'll probably want to wrap the array of MyClass in an object that knows how it was allocated: Code: |
template<class T, int kSize, class Allocator>
class Wrapper
{
// implement 'new' and 'delete' here, in terms of Allocator.
MyClass array[kSize];
};
|
If you need kSize to be a variable, you'll have to store the size as a data member and allocate a variable sized struct.
sniper, where did you hear that delete[] is no longer necessary?
#156792 - sniper - Tue May 13, 2008 11:45 pm
sajiimori yes you are right.
If you use delete instead of delete[] only the first destructor is called. So you should use delete [].
Code: |
#include <iostream>
using namespace std;
class x
{
static int count;
public:
x()
{
cout<<"constructor"<<count++<<endl;
}
~x()
{
cout<<"destructor"<<--count<<endl;
}
};
int x::count = 0;
int main()
{
x *y;
cout<<"delete[]:"<<endl;
y = new x[3];
delete [] y;
cout<<"\ndelete:"<<endl;
y = new x[3];
delete y;
return 0;
} |
#156805 - tepples - Wed May 14, 2008 12:53 am
In the ideal situation that I imagine, new T would have been an alias for new T[1], storing 1 in the allocation's header. Then delete dave could be made an alias for delete[] dave. But then that would have made sense.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#156830 - pepsiman - Wed May 14, 2008 1:34 pm
tepples wrote: |
In the ideal situation that I imagine, new T would have been an alias for new T[1], storing 1 in the allocation's header. |
You cannot pass arguments to the constructor with new T[1].
#156836 - PeterM - Wed May 14, 2008 4:56 pm
Simon,
We had a similar problem with our allocation stuff in work. Unfortunately I can't remember the details of how we fixed it.
Custom array news/deletes are a real pain.
Give me a shout if you still need help and I'll see what I can dig up.
Pete
_________________
http://aaiiee.wordpress.com/