Topic: On delete []...


Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: 2000/10/09
Raw View
In article <SPkE5.63878$O95.4696207@typhoon.tampabay.rr.com>, Scott
Robert Ladd <scottrobertladd@hotmail.com> writes
>// example 2
>char * ca = new char[100];
>//...
>delete ca;
>
>Note the lack of "array brackets" with the delete in example 2. My coworker
>explains "it's just an array of char", and resists including the "[]" with
>his deletions of char arrays. His argument: characters are a single
>allocation unit in length, therefore the delete operator doesn't need to do
>any special math or destructor calls to free the memory pointed to by ca.
>
>In all likelihood, example 2 will compile and run; I am concerned, however,
>about memory leaks in a program that runs as a daemon or service.

The argument given is often that it does not matter if the array is of a
type that has a trivial dtor. However many systems allocate extra
storage to contain housekeeping information and place this before the
start of the array. That means that the address returned by new[] is not
the address of the dynamically allocated block of memory. Now if you use
delete, the address will not be adjusted to cater for housekeeping
space. The result is that the deallocation function will try to
deallocate the wrong block of memory. What happens then depends on how
the OS handles this problem. At least some will terminate the guilty
process.



Francis Glassborow      Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Jens Kilian <Jens_Kilian@agilent.com>
Date: 2000/10/10
Raw View
"Scott Robert Ladd" <scottrobertladd@hotmail.com> writes:
> However, one of my coworkers insists that there is nothing wrong with:
>
> // example 2
> char * ca = new char[100];
> //...
> delete ca;

This is non-portable.  I've known at least one compiler (HP C++ on HP-UX,
which is obsolete by now) which allocated arrays from a special arena, and
which would leak memory if you deleted an array using simple delete.
(The leak was in a hash table by which the run-time system kept track of
the sizes of allocated arrays.)

Bye,
 Jens.
--
mailto:jjk@acm.org                 phone:+49-7031-464-7698 (HP TELNET 778-7698)
  http://www.bawue.de/~jjk/          fax:+49-7031-464-7351
PGP:       06 04 1C 35 7B DC 1F 26 As the air to a bird, or the sea to a fish,
0x555DA8B5 BB A2 F0 66 77 75 E1 08 so is contempt to the contemptible. [Blake]

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: "Scott Robert Ladd" <scottrobertladd@hotmail.com>
Date: 2000/10/09
Raw View
I've always been a believer is "an array allocated is an array deleted," as
in:

// example 1
int * ia = new int[100];
//...
delete [] ia;

The above is good programming practice, I'm sure most of us will believe.

However, one of my coworkers insists that there is nothing wrong with:

// example 2
char * ca = new char[100];
//...
delete ca;

Note the lack of "array brackets" with the delete in example 2. My coworker
explains "it's just an array of char", and resists including the "[]" with
his deletions of char arrays. His argument: characters are a single
allocation unit in length, therefore the delete operator doesn't need to do
any special math or destructor calls to free the memory pointed to by ca.

In all likelihood, example 2 will compile and run; I am concerned, however,
about memory leaks in a program that runs as a daemon or service.

Part of my mandate is portable code (we have a universal library wrapped in
a platform-specific shell), and considering my coworker's respect for this
group, I'm hoping people here will back me in saying that "delete []" is
required for any array allocated by new, no matter what the type of the
elements.

** Scott Robert Ladd    http://coyotegulch.com



---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: kuehl@ramsen.informatik.uni-konstanz.de (Dietmar Kuehl)
Date: 2000/10/09
Raw View
Hi,
Scott Robert Ladd (scottrobertladd@hotmail.com) wrote:
: Part of my mandate is portable code (we have a universal library wrapped in
: a platform-specific shell), and considering my coworker's respect for this
: group, I'm hoping people here will back me in saying that "delete []" is
: required for any array allocated by new, no matter what the type of the
: elements.

There is nothing special about the type 'char': An array object
'array' of 'char's has to be deleted using 'delete[] array' like any
other array object. The result of failing to obey this rule is
undefined behavior. Since there may be different pools where memory is
allocacted from (eg. a specialized pool for objects with 'sizeof(T) ==
1' can greatly reduce memory requirements), using the wrong form of
delete can result in severe corruption. Just because it does work with
typical implementations should not lure people into the assumption that
implementations will not provide optimized allocators in future
versions of the library - although I would expect that most vendors
will shy away from this because suddenly "working" programs would start
to fail...
--
<mailto:dietmar_kuehl@yahoo.de>
<http://www.fmi.uni-konstanz.de/~kuehl/>
I am a realistic optimist - that's why I appear to be slightly pessimistic

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: brahms@mindspring.com (Stan Brown)
Date: 2000/10/09
Raw View
[This followup was also e-mailed to the cited author for speed.
Please follow up in the newsgroup.]

Scott Robert Ladd <scottrobertladd@hotmail.com> wrote in
comp.std.c++:
>one of my coworkers insists that there is nothing wrong with:
>
>// example 2
>char * ca = new char[100];
>//...
>delete ca;

Point him at the FAQ list (URL in my sig), specifically at "[16.12]
Can I drop the [] when deleteing array of some built-in type (char,
int, etc)?" at <http://www.parashift.com/c++-faq-lite/freestore-
mgmt.html#[16.12]>.

--
Stan Brown, Oak Road Systems, Cortland County, New York, USA
                                  http://oakroadsystems.com
C++ FAQ Lite: http://www.parashift.com/c++-faq-lite/
the C++ standard: http://webstore.ansi.org/
reserved C++ identifiers: http://oakroadsystems.com/tech/cppredef.htm
more FAQs: http://oakroadsystems.com/tech/faqget.htm

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: James Dennett <james@evtechnology.com>
Date: 2000/10/09
Raw View
Scott Robert Ladd wrote:

> I've always been a believer is "an array allocated is an array deleted," as
> in:
>
> // example 1
> int * ia = new int[100];
> //...
> delete [] ia;
>
> The above is good programming practice, I'm sure most of us will believe.

And required by the C++ Standard.

>From 5.3.5/2: "In the first alternative (delete object), the value of the operand of delete shall be a pointer to a non-array object or a pointer to a sub-object (1.8) representing a base class of sucha n object (clause 10).  If not, the behavior is
undefined.  In the second alternative (delete array), the value of the operand of delete shall be the pointer value which resulted from a previous array new-expression.  if not, the behavior is undefined."

> However, one of my coworkers insists that there is nothing wrong with:
>
> // example 2
> char * ca = new char[100];
> //...
> delete ca;
>
> Note the lack of "array brackets" with the delete in example 2. My coworker
> explains "it's just an array of char", and resists including the "[]" with
> his deletions of char arrays. His argument: characters are a single
> allocation unit in length, therefore the delete operator doesn't need to do
> any special math or destructor calls to free the memory pointed to by ca.

But the implementation may keep separate pools of memory for objects and arrays, and there is an array (rather than a single object) as ca.  Writing "delete ca" is wrong, though it will work with many implementations.

It will also behave strangely when you want to instrument operator new etc.

> In all likelihood, example 2 will compile and run; I am concerned, however,
> about memory leaks in a program that runs as a daemon or service.

You should also be concerned about memory corruption and other run-time failures.  I believe that a compiler could legitimately also refuse to accept (at compile time) code such as
  char *a = new char[100];  delete a;
because it can do what it likes for a program which invokes undefined behavior.  Certainly a warning would be nice, though I don't know of any compiler which issues one.

> Part of my mandate is portable code (we have a universal library wrapped in
> a platform-specific shell), and considering my coworker's respect for this
> group, I'm hoping people here will back me in saying that "delete []" is
> required for any array allocated by new, no matter what the type of the
> elements.
>
> ** Scott Robert Ladd    http://coyotegulch.com

There are simple rules:
(i) Any object allocated with new must be de-allocated (if at all) by delete, not delete [].
(ii) Any array allocated with new [] must be de-allocated (if at all) by delete[], not delete.

These are as inflexible as rules prohibiting mixing of new/free and malloc/delete.

-- James Dennett <jdennett@acm.org>


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: "John D. Hickin" <hickin@cam.org>
Date: 2000/10/09
Raw View

----- Original Message -----
From: "Scott Robert Ladd" <scottrobertladd@hotmail.com>
Newsgroups: comp.std.c++
Sent: Monday, October 09, 2000 11:14
Subject: On delete []...


> I've always been a believer is "an array allocated is an array deleted,"
as
> in:
>
> // example 1
> int * ia = new int[100];
> //...
> delete [] ia;
>
> The above is good programming practice, I'm sure most of us will believe.

Yes, and it is also the only safe way to get the job done.

>
> However, one of my coworkers insists that there is nothing wrong with:
>
> // example 2
> char * ca = new char[100];
> //...
> delete ca;
>
> Note the lack of "array brackets" with the delete in example 2. My
coworker
> explains "it's just an array of char", and resists including the "[]" with

Tell him that:

- the standard allows you to replace global operator new and delete.
- it allows you to replace global new[] and delete[].
- it does not specify that your delete has to work correctly on something
that came from your new[].
- it does not specify that your delete[] need work correctly on something
that came from your new.

You may, therefore, replace the standard functions as follows:

- operator new() calls malloc
- operator delete() delete calls free
- operator new[]() over-allocates using malloc and passes a pointer to the
inside of the allocated block
- operator delete[]() backs off its pointer before calling free

In this case, the likely result of delete(new[]) or of delete[](new) is a
crash.


Regards, John.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]