Wednesday, May 03, 2006

Memory, memory

"Always delete what you new, and free what you malloc, never mix new with free or malloc with delete."

The reason for this is that if you do that, then the behavior is technically undefined because there is no guarantee that new would internally use malloc, or that delete would internally use free.

Also, never mix scalar new with vector delete. This will result in memory leaks.

Test* t = new Test[3];
delete t;


I'm not sure that's right. I think delete t is OK.

Or worse:
Test* t = new Test;
delete[] t;


Why? Because the pointer returned by the new[] operator is not the start of the allocated memory but instead points to Test[0]. Huh? Isn't Test[0] the beginning of the memory block? N0! When using scalar new the complier keeps track of the number of items that have been allocated. This makes complete sense. However, we forget that part of the allocated memory includes this additional word of information! So in short - Vector New'd memory does not look like Scalar New'd memory!

It's a little more clear when we take a look at the vector deleting destructor (pseudo-code):

void MyClass::vector deleting destructor (int flags)
{
if (flags & 2) // vector destruct
{
size_t* a = reinterpret_cast(this) - 1;
size_t howmany = *a;
vector destructor iterator (p,
sizeof(MyClass),
howmany,
MyClass::~MyClass);

if (flags & 1) // vector delete
{
operator delete(a);
}
}
else // scalar destruct
{
this->~MyClass(); // destruct one
if (flags & 1) // scalar delete
{
operator delete(this);
}
}
}



"If you have to use strcpy, use strncpy instead!"

char buf_a[16];
char buf_b[256];
...
strcpy (buf_a, buf_b);
// This is really bad!


The problem here is that the developer has forgotten that when using strcpy one must be aware of the size of the buffers being copied. By makeing a rule of always using strncpy instead of strcpy,

0 Comments:

Post a Comment

<< Home