kevin@msa3b.UUCP (Kevin P. Kleinfelter) (04/29/91)
I'm reading along in a book about C++, and I see that one can do: char *s; s = new char [40]; ... delete s; The book then goes on to say that one should: int *p; p = new int [40]; ... delete 40 p; These examples seem to suggest to me that one specifies the number of bytes to delete with int pointers but not char pointers. Either I'm confused or the book is! True or False: If one wants to delete all of the 'new-ed' storage one need not specify the quantity to delete, just the pointer to the storage. -- Kevin Kleinfelter @ Dun and Bradstreet Software, Inc (404) 239-2347 ...gatech!nanovx!msa3b!kevin Warning: There seem to be multiple 'msa3b' nodes on Usenet, and it is nanoVX, not nanovAx.
pal@xanadu.wpd.sgi.com (Anil Pal) (05/01/91)
In article <1619@msa3b.UUCP>, kevin@msa3b.UUCP (Kevin P. Kleinfelter) writes: |> I'm reading along in a book about C++, and I see that one can do: |> |> char* s = new char [40]; |> delete s; |> |> int *p = new int [40]; |> delete 40 p; |> |> Either I'm confused or the book is! Actually, both of these examples are incorrect as of the latest draft of the C++ standard. The correct way (for both cases) is: mumble* x = new mumble[40]; delete [] x; Earlier implementations of C++ (for example, those based on cfront 2.0 or before) required the programmer to explicitly supply the count (40) in the delete. What happens if you forget and do a simple delete x; ? Well, for the examples quoted (int and char) usually nothing dramatic. The full storage will probably be returned to the free pool (in typical malloc/free based implementations). If the type mumble is a class with a destructor, however, forgetting the array form of the delete will result in a single destructor being called, for the 0-th element in the array. Using the array syntax (delete [] x;) will correctly call the destructor for all elements of the array. -- Anil A. Pal, Silicon Graphics, Inc. pal@wpd.sgi.com (415)-335-7279
rmartin@clear.com (Bob Martin) (05/01/91)
In article <1619@msa3b.UUCP> kevin@msa3b.UUCP (Kevin P. Kleinfelter) writes: >I'm reading along in a book about C++, and I see that one can do: > > char *s; > s = new char [40]; > ... > delete s; > >The book then goes on to say that one should: > > int *p; > p = new int [40]; > ... > delete 40 p; > >True or False: If one wants to delete all of the 'new-ed' storage one need > not specify the quantity to delete, just the pointer to the > storage. Kevin: In the ARM section 5.3.4 there is a discussion about delete and arrays. You must use the form delete [] otherwise the operation is "undefined" and you will probably encounter odd execution errors. char *s; s = new char [40]; ... delete [] s; And the same goes for ints, longs, doubles, classes, etc. So the answer to your query is "True" but with the added qualifier that when deleting an array one must use the delete [] form of the operator. -- +-Robert C. Martin-----+:RRR:::CCC:M:::::M:| Nobody is responsible for | | rmartin@clear.com |:R::R:C::::M:M:M:M:| my words but me. I want | | uunet!clrcom!rmartin |:RRR::C::::M::M::M:| all the credit, and all | +----------------------+:R::R::CCC:M:::::M:| the blame. So there. |
jimad@microsoft.UUCP (Jim ADCOCK) (05/16/91)
In article <2210002@hpfelg.HP.COM> greg@hpfelg.HP.COM (Greg Begay) writes: |>True or False: If one wants to delete all of the 'new-ed' storage one need |> not specify the quantity to delete, just the pointer to the |> storage. |>-- | |True if the pointer is to storage containing homogenious data (ie, one type |of data). What if you want to free the storage of an array of objects? |How will the compiler know to call the destructors (and how many |destructors to call) for the objects in the array? I disagree -- in theory. ARM page 64 calls for programmers to use: delete [] ptrthingee where ptrthingee is some kind of an expression referring to some kind of array allocated via new. and programmers to use: delete ptrthingee where ptrthingee is some kind of an expression referring to some kind of individual item allocated via new. However, in practice, C++ compiler implementations today vary so widely in what they expect that all one can do is experiment and try to discover the behavior of one's compiler. Many implementations are "busted" in one way or another, so be prepared for the unexpected. The language could have been designed such that the allocation routines were required to keep track of how many objects [1 to N] are being allocated, what size and types those objects are, etc, but this was considered to be too much overhead. By requiring programmers to specify the [] when deleting arrays, implementors are given the option of using separate allocation schemes for arrays vs individual objects -- with the remembering number of elements allocated [and hence needing to be destroyed] only required for array allocations. Also, implementations might want to specialize their allocation schemes under the assumption that individual object allocations are typically quite small, whereas array allocations can be quite big. Unfortunately, all this comes down to inherent problems with the multiple overloaded meanings of a "pointer" in C/C++: 1) a reference to an individual object or 2) a reference to an array or 3) a reference to a start of an array or 4) a reference to an element in an array or 5) a reference to whatever would be one past the end of an array if such object actually existed or 6) a byte address of what programmers typically mistakenly refer to as physical memory but which is actually, usually, a reference to a virtual address of a relocatable group of bytes, said fact cleverly hidden from some programmers in some simple situations via a complicated system of software/firmware/hardware, and not hidden at all from programmers in more complicated situations, such as those doing "object oriented programming." This situation could have been somewhat repaired had C++ provided enough power to C++ "references" that they could have been commonly used instead of pointers. But, this is presumably water under the bridge.