Click to See Complete Forum and Search --> : new and delete operator


strange
March 29th, 2004, 02:36 PM
Hi,

I've found some strange behaviour of the new and delete operators.

The following code overwrites the new, new[], delete and delete[] operators, adding a message being printed every time they are called. Then I use each operator once and get some unexpected behaviour. The code is:


#include <iostream>
#include <vector>

using namespace std;

inline void* operator new (unsigned int size)
{
cout << "new: " << size << "\n";
return malloc(size);
}

inline void* operator new[] (unsigned int size)
{
cout << "new[]: " << size << "\n";
return malloc(size);
}

inline void operator delete (void * buf)
{
cout << "delete\n";
free(buf);
}

inline void operator delete[] (void * buf)
{
cout << "delete[]\n";
free(buf);
}

#pragma argsused
int main (char * argv, unsigned int argc)
{
vector<int> *var = new vector<int>;
vector<int> *arr = new vector<int>[1];

delete var;
delete[] arr;


return 0;
}


and the program output is:

new: 32
new[]: 36
delete
delete
delete


leaving two questions:
[list=1]
why are there two 'delete's and no 'delete[]'?
why is an array with size 1 four bytes larger than a plain variable? (with integer this is NOT the case)
[/list=1]

Thanks!

Paul McKenzie
March 29th, 2004, 03:12 PM
Originally posted by strange
[list=1]
why are there two 'delete's and no 'delete[]'?
why is an array with size 1 four bytes larger than a plain variable? (with integer this is NOT the case)
[/list=1]

Thanks! Compiler? Version?

I do not get that output when I run on Visual C++ 6.0.

new: 16
new[]: 20
delete
delete
delete
delete[]

why is an array with size 1 four bytes larger than a plain variable? (with integer this is NOT the case)Because that's how the compiler handles things vis-a-vis the two versions of operator new. Maybe using the array new adds another field to the internal structure used to keep track of allocations, I don't know. In any event, the compiler code generation needs to do it, and the only ones that really know what it's for are the compiler writers.
why are there two 'delete's and no 'delete[]'?The reason for two deletes is that the first delete is for the internal buffer that vector has allocated, and the second delete is for the fact you used operator new to create the vector. Why your version does not have "delete[]" -- maybe your compiler does not support overloading of operator delete[] correctly.

Regards,

Paul McKenzie

strange
March 29th, 2004, 03:32 PM
Thanks,

compiler is Borland C++ 5.5.1

Sam Hobbs
March 29th, 2004, 06:58 PM
I think it helps to be able to match an allocation with a deletion, so it helps to have the allocated buffer addresses. I used the following (excluding headers):
unsigned int SizesCount=0;
struct OperationsStruct {
unsigned int Size;
void *Allocation;
char Operation;
};
OperationsStruct Operations[100];

inline void* operator new (unsigned int size)
{
Operations[SizesCount].Size = size;
Operations[SizesCount].Allocation = malloc(size);
Operations[SizesCount].Operation = 'n';
return Operations[SizesCount++].Allocation;
}

inline void* operator new[] (unsigned int size)
{
Operations[SizesCount].Size = size;
Operations[SizesCount].Allocation = malloc(size);
Operations[SizesCount].Operation = '[';
return Operations[SizesCount++].Allocation;
}

inline void operator delete (void * buf)
{
Operations[SizesCount].Size = 0;
Operations[SizesCount].Allocation = buf;
Operations[SizesCount].Operation = 'd';
++SizesCount;
free(buf);
}

inline void operator delete[] (void * buf)
{
Operations[SizesCount].Size = 0;
Operations[SizesCount].Allocation = buf;
Operations[SizesCount].Operation = ']';
++SizesCount;
free(buf);
}

// #pragma argsused
int main (char * argv, unsigned int argc)
{
vector<int> *var = new vector<int>;
vector<int> *arr = new vector<int>[1];
int i;

delete var;
delete[] arr;

for (i=0; i<SizesCount; ++i)
cout << Operations[i].Operation << ' '
<< Operations[i].Allocation << ' '
<< Operations[i].Size << '\n';

return 0;
}And got:

n 00320FE0 40
n 00321038 33
n 00321090 16
[ 003210D8 20
d 00000000 0
d 00321090 0
d 00000000 0
] 003210D8 0
n 00321090 8
n 003210C8 33
n 00321120 33
d 00321120 0
d 003210C8 0
n 003210C8 24
n 00321110 33
n 00321168 33
[ 003211C0 1
[ 003211F8 6
[ 00321230 5
d 00321168 0
d 00321110 0

I have not attempted to interpret that, but I hope it helps to show what is happening.