|
-
July 13th, 2010, 09:19 AM
#1
delete[] mechanics
Hey all,
I've looked all over for how delete[] *exactly* works. I *thought* it just performed the delete operation until it found a null, but this seems wrong.
Could someone explain if this leaks memory or not?
char a = new char[50];
a[0] = '\0';
delete[] a;
Also, what is there a defined behavior for
char a = new char[50];
delete[] &a[7];
When delete[] is called, does it look up how much memory was allocated to this starting address then clean it all up? All the documentation just says it frees memory for the corresponding new[].
Thanks!
-
July 13th, 2010, 09:29 AM
#2
Re: delete[] mechanics
 Originally Posted by spelltwister
Could someone explain if this leaks memory or not?
char a = new char[50];
a[0] = '\0';
delete[] a;
It shouldn't even compile.
You can't assign a char pointer to a char.
Also, what is there a defined behavior for
char a = new char[50];
delete[] &a[7];
It shouldn't even compile.
If a was a char * then the answer is no!
When delete[] is called, does it look up how much memory was allocated to this starting address then clean it all up?
Yes
"It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong."
Richard P. Feynman
-
July 13th, 2010, 09:39 AM
#3
Re: delete[] mechanics
Yes, I did mean
char* a = new char[50];
Do you have any source you can reference where it says it looks up allocated space to delete it? I've looked on msdn, and various other places and nothing mentions how it actually does the freeing of memory.
Thanks!
-
July 13th, 2010, 09:46 AM
#4
Re: delete[] mechanics
delete[] also calls destructors, btw, it doesn't just free memory. new and delete eventually end up using malloc and free. The operating system actually determines how to allocate and deallocate memory. It will be different on different platforms.
-
July 13th, 2010, 09:46 AM
#5
Re: delete[] mechanics
 Originally Posted by spelltwister
Yes, I did mean
char* a = new char[50];
Do you have any source you can reference where it says it looks up allocated space to delete it? I've looked on msdn, and various other places and nothing mentions how it actually does the freeing of memory.
Thanks!
That's because it is 100% implementation defined. And the OS is usually involved too.
There are papers out there that explain the different ways of doing it, but onless you are a compiler writter, you have no need to know.
Is your question related to IO?
Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.
-
July 13th, 2010, 09:47 AM
#6
Re: delete[] mechanics
 Originally Posted by spelltwister
Yes, I did mean
char* a = new char[50];
Do you have any source you can reference where it says it looks up allocated space to delete it? I've looked on msdn, and various other places and nothing mentions how it actually does the freeing of memory.
Thanks!
This took less than a minute to find.
http://www.parashift.com/c++-faq-lit...html#faq-16.14
-
July 13th, 2010, 10:28 AM
#7
Re: delete[] mechanics
 Originally Posted by GCDEF
I like the short answer 
Looks like g++ doesn't use the first approach. A quick inspection of the memory just before a test array doesn't show any signs of it's size.
-
July 13th, 2010, 11:22 AM
#8
Re: delete[] mechanics
 Originally Posted by GCDEF
Thanks for the reply. I'm glad ur skills of using searching exceed mine ;D Is there a way to query for the allocated space? For instance, is there a way to:
char* c = new char[50];
... more code that may affect c ...
int space = query_for_space_allocated(c);
int chars_allocated = space / sizeof(char);
I didn't think this was possible, but if the system knows, why can't we get that information?
-
July 13th, 2010, 11:30 AM
#9
Re: delete[] mechanics
 Originally Posted by spelltwister
If the system knows, why can't we get that information?
Because not all pointers point to dynamically allocated memory, and hence, the information is not always available.
If you create an array on the stack, and pass it to a function, the array decays into a pointer, and there is absolutely no information about the size associated.
Is your question related to IO?
Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.
-
July 13th, 2010, 12:09 PM
#10
Re: delete[] mechanics
 Originally Posted by spelltwister
Thanks for the reply. I'm glad ur skills of using searching exceed mine ;D Is there a way to query for the allocated space? For instance, is there a way to:
char* c = new char[50];
... more code that may affect c ...
int space = query_for_space_allocated(c);
int chars_allocated = space / sizeof(char);
I didn't think this was possible, but if the system knows, why can't we get that information?
The answer is to quit using raw arrays and use container classes such as std::vector that has all of this information.
Regards,
Paul McKenzie
-
July 13th, 2010, 12:25 PM
#11
Re: delete[] mechanics
Hmm, that is an interesting question. It is strange that you can't get that information. It's possible that such a function does exist on some of the platforms. Obviously it would have to return an error case or throw an exception for stack arrays.
Anyway, what are you doing that you require the size anyway? You could always create a wrapper class:
Code:
template <typename T>
class array{
public:
array(size_t size){
internal = new _array(size);
}
array(const array & orig){
internal = orig.internal;
++internal -> refcount;
}
~array(void){
deref();
}
size_t size() const{
return internal -> size();
}
T & operator[](size_t pos){
CopyOnWrite();
return internal -> at(pos)
}
const T & operator[](size_t pos) const {
return internal -> at(pos);
}
private:
void CopyOnWrite(void){
if (internal -> refcount > 1){
_array * orig = internal;
--orig -> refcount;
internal = new _array(orig -> size());
//can't memcopy because these are objects
for(unsigned int i = 0; i < size(); ++i){
internal -> at(i) = orig -> at(i);
}
}
}
void deref(void){
--internal -> refcount;
if (!internal -> refcount) delete internal;
}
_array * internal;
struct _array {
public:
_array(size_t _size){
mysize = _size;
myarray = new T[_size];
refcount = 1;
}
~_array(void){
assert(refcount == 0;)
delete[] myarray;
}
size_t size() const {
return mysize;
}
T & at(size_t pos){
assert(pos > size());
return myarray[pos]
}
const T & at(size_t pos) const {
assert(pos > size());
return myarray[pos];
}
private:
T * myarray;
size_t mysize;
size_t refcount;
};
}
Wrote it fast, have no idea if it's right, but you get the idea. I wrote a reference counting wrapper around the wrapper because it makes it faster to pass around by value, but you can just use the _array structure if you'd like.
Last edited by ninja9578; July 13th, 2010 at 12:44 PM.
-
July 13th, 2010, 12:39 PM
#12
Re: delete[] mechanics
 Originally Posted by ninja9578
Wrote it fast, have no idea if it's right, but you get the idea. Even better, you could wrap another wrapper around this one to do reference counting to make passing it around even faster.
Reference counting will not make passing it around even faster, because you cannot really beat the compiler generated copy constructor and copy assignment operator's shallow copying 
If you really do want such a class, I suggest that it be named something other than array, and have its constructor declared explicit.
-
July 13th, 2010, 12:40 PM
#13
Re: delete[] mechanics
Too late, I edited it with a reference counting. And it's not a shallow copy, there is stuff in the array.
-
July 13th, 2010, 12:46 PM
#14
Re: delete[] mechanics
 Originally Posted by ninja9578
Too late, I edited it with a reference counting. And it's not a shallow copy, there is stuff in the array.
Ah, but before you added reference counting, it would be mere shallow copying. Now you still have missed out the copy assignment operator.
EDIT:
Yes, I recall something like this in Boost: boost::shared_array.
Last edited by laserlight; July 13th, 2010 at 12:51 PM.
-
July 13th, 2010, 12:51 PM
#15
Re: delete[] mechanics
Ah yes, the copy assignment operator, I always forget to write that one.
Code:
array & operator = (const array & orig){
internal = orig.internal;
++internal -> refcount;
return *this;
}
Yes, my original code was using a shallow copy, but then I realized how dumb that was, seeing as the destructor deleted the array and anything that had been shallow copied would become invalid.
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|