Thursday, September 11, 2008

Events versus delegates in C#

Finally somebody clearly defined the difference between C# events and multicast delegates.

We have seen that the event keyword is a modifier for a delegate declaration that allows it to be included in an interface, constraints it invocation from within the class that declares it, provides it with a pair of customizable accessors (add and remove) and forces the signature of the delegate (when used within the .NET framework).

Tuesday, July 1, 2008

"delete []" versus just "delete" in C++

This week I was asked for the second time to "fix" a bug in my code and use "delete []" on arrays instead of "delete". I did an informal survey and all of the people I asked told me using plain "delete" on arrays is wrong.

As I remembered that it is ok, I decided to do some experiments.

I wrote this code and compiled it in VS2008:

#include "stdafx.h"
TCHAR * buf = NULL;
int * intbuf = NULL;

class Foo
int x;
// ~Foo() { x = 2; }
Foo * fooBuf = NULL;

int _tmain(int argc, _TCHAR* argv[])
delete buf;
delete [] buf;
delete intbuf;
delete [] intbuf;
delete fooBuf;
delete [] fooBuf;
return 0;

Now let us check the disassembly:

delete buf;
003E1000 mov eax,dword ptr [buf (3E3370h)]
003E1005 push eax
003E1006 call operator delete (3E105Ch)
delete [] buf;
003E100B mov eax,dword ptr [buf (3E3370h)]
003E1011 push eax
003E1012 call operator delete (3E105Ch)

delete intbuf;
003E1017 mov eax,dword ptr [intbuf (3E3374h)]
003E101D push eax
003E101E call operator delete (3E105Ch)
delete [] intbuf;
003E1023 mov eax,dword ptr [intbuf (3E3374h)]
003E1028 push eax
003E1029 call operator delete (3E105Ch)

delete fooBuf;
003E102E mov eax,dword ptr [fooBuf (3E3378h)]
003E1034 push eax
003E1035 call operator delete (3E105Ch)
delete [] fooBuf;
003E103A mov eax,dword ptr [fooBuf (3E3378h)]
003E1040 push eax
003E1041 call operator delete (3E105Ch)

003E1046 add esp,18h

return 0;

All identical.

Now if you uncomment the destructor interesting things start to happen on the last two deletes:

delete fooBuf;
002C103E mov eax,dword ptr [fooBuf (2C3378h)]
002C1043 add esp,10h
002C1046 test eax,eax
002C1048 je wmain+71h (2C1081h)
002C104A push eax
002C104B mov dword ptr [eax],2
002C1051 call operator delete (2C1094h)
002C1056 mov eax,dword ptr [fooBuf (2C3378h)]
002C105B add esp,4

delete [] fooBuf;
002C105E test eax,eax
002C1060 je wmain+71h (2C1081h)
002C1062 mov ecx,dword ptr [eax-4]
002C1065 push esi
002C1066 lea esi,[eax-4]
002C1069 push offset Foo::~Foo (2C1000h)
002C106E push ecx
002C106F push 4
002C1071 push eax
002C1072 call `eh vector destructor iterator' (2C10F8h)
002C1077 push esi
002C1078 call operator delete (2C1094h)
002C107D add esp,4
002C1080 pop esi

The calls are very different because in second case it goes through the array and destructs individual elements, while in the first just deletes the memory.

“delete” and “delete []” are equivalent unless the array contains objects and that objects have a destructor.

This said it is still probably good idea to use "delete []" for the clarity alone.

Tuesday, June 10, 2008

.NET Zero

I second digitalnetbizz.

The most amazing book about .NET is free and is available at Charles Petzold's web site.

In general check out everything written by Charles. He is a category of his own among technology writers.