Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!usc!snorkelwacker!bloom-beacon!eru!hagbard!sunic!mcsun!ukc!dcl-cs!aber-cs!athene!pcg From: pcg@cs.aber.ac.uk (Piercarlo Grandi) Newsgroups: comp.lang.c++ Subject: Re: ``delete[]p'' -- where is the actual size of *p stored? Message-ID: Date: 31 Aug 90 19:34:26 GMT References: <56956@microsoft.UUCP> <1180@fornax.UUCP> Sender: pcg@aber-cs.UUCP Organization: Coleg Prifysgol Cymru Lines: 72 In-reply-to: miron@fornax.UUCP's message of 30 Aug 90 04:34:52 GMT On 30 Aug 90 04:34:52 GMT, miron@fornax.UUCP (Miron Cuperman) said: miron> jimad@microsoft.UUCP (Jim ADCOCK) writes: jimad> In article jimad> cline@sun.soe.clarkson.edu (Marshall Cline) writes: cline> B* p = new D[100]; cline> delete [] p; jimad> C++ will already "do the wrong thing" with any attempts to jimad> address the d's referred to by p, thus rendering any problems jimad> with delete [] p moot. miron> This is not correct. Jim Adcock did not say it explicitly, but you are casting a (D[100]) to a (B *), and so doing you lose two types of information: that we are addressing entities of type D, and 100 of them, because Marshall Cline's assignment is really read by the compiler as: B *p = &((new D[100])[0]); i.e. p becomes a pointer to the zero'th element of the array. This means that it becomes impossible for the compiler to know that when you write p[i] it must implement it as something like '(B *) ((char *) p + i*sizeof (D))'; it will instead transform it to '(B *) ((char *) p + i*sizeof (B))'. The two expression will only be equivalent when i == 0, and only because inheritance is implemented as prefixing. miron> A pointer to an object may be cast to a pointer to a base class miron> of that object. Therefore the above syntax is correct. The syntax is correct. The compiler will also correctly addres *p; anything else is undefined, because all you have is a pointer to a single object. Remember, in C and C++ you are only allowed to do things like *(p + i) if you *know* that p points to an array of object os the same type as *p, and in this case this is not true. miron> From what I understand, the C++ implementation must save the length of miron> the array in bytes, and deallocate it accordingly. The problem as discussed above is not about the size. jimad> The right thing is for a compiler to issue a stern warning on jimad> the new array statement assigned to an incompatible pointer. The right thing would be for the rule that allows a base pointer to a derived class object to be abolished. It has all the insecurity of being too clever with pointers to unions. Same goes for object assignment. If you want to do polymorphism, there are ways to do it within the language, and they are documentedly hazardous. Polymorphism is (conceptually) difficult, and trying to pretend otherwise is not very nice. Another right thing would be to stop pretending that C/C++ really has arrays; C/C++'s array are really just a polite way of reserving memory for a pointer to roam about -- real arrays carry with them a descriptor. We do have something like a[M][N] in C/C++, but then multi dimensional arrays cause lots of trouble in C/C++ and maybe should be simply expunged. This is probably the right course in C++, which has mechanisms to define within the language proper, descriptor based, arrays. -- Piercarlo "Peter" Grandi | ARPA: pcg%uk.ac.aber.cs@nsfnet-relay.ac.uk Dept of CS, UCW Aberystwyth | UUCP: ...!mcsun!ukc!aber-cs!pcg Penglais, Aberystwyth SY23 3BZ, UK | INET: pcg@cs.aber.ac.uk