Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > realloc() implicit free() ?

Reply
Thread Tools

realloc() implicit free() ?

 
 
CBFalconer
Guest
Posts: n/a
 
      05-21-2005
Robert Gamble wrote:
> On Fri, 20 May 2005 17:54:45 +0000, CBFalconer wrote:
>> tigervamp wrote:
>>

.... snip ...
>>>
>>> No, the behavior is well defined by the Standard, see section
>>> 7.20.3 of C99, I don't have a C89 copy handy.

>>
>> No, I don't consider it well defined. It leaves too much up to
>> the implementation in the case of zero block size requests.

>
> I was referring specifically to the behavior of realloc
> deallocating the original object which is well defined.
>
>> This means that NULL is not always a sign of failure, and that
>> a non-NULL return is not necessarily freeable or reallocable.

>
> NULL is always a sign of failure when the size provided is
> non-zero, if you want to provide a size of zero is is easy
> enough to handle the return
>
> What evidence do you have that a non-NULL value returned by
> realloc, when provided a size of zero, cannot safely be passed
> to free() or realloc()?


As I read the following from N869:

7.20.3 Memory management functions

[#1] The order and contiguity of storage allocated by
successive calls to the calloc, malloc, and realloc
functions is unspecified. The pointer returned if the
allocation succeeds is suitably aligned so that it may be
assigned to a pointer to any type of object and then used to
access such an object or an array of such objects in the
space allocated (until the space is explicitly freed or
reallocated). Each such allocation shall yield a pointer to
an object disjoint from any other object. The pointer
returned points to the start (lowest byte address) of the
allocated space. If the space cannot be allocated, a null
pointer is returned. If the size of the space requested is
zero, the behavior is implementation-defined: either a null

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^
pointer is returned, or the behavior is as if the size were
some nonzero value, except that the returned pointer shall
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
not be used to access an object. The value of a pointer
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
that refers to freed space is indeterminate.

Is freeing NULL so generated accessing an object? Is freeing
non-NULL so generated accessing an object? When things are buried
in layers of code we can easily guarantee that the pointer was
created by malloc/realloc, and we can even guard it by making it
NULL after passing to free, but that guard won't work if realloc
can return a non-freeable pointer.

--
Some informative links:
news:news.announce.newusers
http://www.geocities.com/nnqweb/
http://www.catb.org/~esr/faqs/smart-questions.html
http://www.caliburn.nl/topposting.html
http://www.netmeister.org/news/learn2quote.html


 
Reply With Quote
 
 
 
 
S.Tobias
Guest
Posts: n/a
 
      05-21-2005
CBFalconer <(E-Mail Removed)> wrote:
> Robert Gamble wrote:
> > On Fri, 20 May 2005 17:54:45 +0000, CBFalconer wrote:


> >> This means that NULL is not always a sign of failure, and that
> >> a non-NULL return is not necessarily freeable or reallocable.


I think you must be misreading something (or I don't understand
what your saying). I'm sure
free(malloc(0));
is _always_ valid.

Have a look at the Rationale, page 160. If `calloc' returned
a non-reallocable pointer, then subsequent reallocations
could no work, could they?

[snip]
> > What evidence do you have that a non-NULL value returned by
> > realloc, when provided a size of zero, cannot safely be passed
> > to free() or realloc()?


> As I read the following from N869:


> 7.20.3 Memory management functions


[snip]
> pointer is returned. If the size of the space requested is
> zero, the behavior is implementation-defined: either a null
>
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^
> pointer is returned, or the behavior is as if the size were
> some nonzero value, except that the returned pointer shall
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> not be used to access an object. The value of a pointer
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> that refers to freed space is indeterminate.


> Is freeing NULL so generated accessing an object?


Null ptrs are special cases. free(NULL) is no-op by definition.

> Is freeing
> non-NULL so generated accessing an object?


No, because the Standard doesn't specify that `free' accesses
the object before deallocation.

I think that `malloc(0)' also allocates an object (if returns non-null),
which may be freed later. The compiler knows the object won't be
accessed, therefore the returned pointer may "point" into some
read-only memory, or may have some invalid/trap value which blows up
when dereferenced.


CBFalconer <(E-Mail Removed)> wrote earlier:

> In my nmalloc implementation for DJGPP I have chosen to treat a
> zero block size as a request for one byte, and let the alignment
> mechanisms raise it as they will.


I'm not criticizing this, there're good reasons to do it like that,
but the Standard does not require the allocated object to have
alignment more than its size, right? Subsequent `malloc(1)'-s could
return ptrs that differ by 1 byte, right? (I'm asking because
the Std is a bit unclear there, IMHO.)

--
Stan Tobias
mailx `echo http://www.velocityreviews.com/forums/(E-Mail Removed)LID | sed s/[[:upper:]]//g`
 
Reply With Quote
 
 
 
 
CBFalconer
Guest
Posts: n/a
 
      05-21-2005
"S.Tobias" wrote:
> CBFalconer <(E-Mail Removed)> wrote earlier:
>
>> In my nmalloc implementation for DJGPP I have chosen to treat a
>> zero block size as a request for one byte, and let the alignment
>> mechanisms raise it as they will.

>
> I'm not criticizing this, there're good reasons to do it like that,
> but the Standard does not require the allocated object to have
> alignment more than its size, right? Subsequent `malloc(1)'-s
> could return ptrs that differ by 1 byte, right? (I'm asking
> because the Std is a bit unclear there, IMHO.)


No, that can't happen. Any non NULL return from
malloc/calloc/realloc must be suitably aligned for any object
whatsoever.

--
Some informative links:
news:news.announce.newusers
http://www.geocities.com/nnqweb/
http://www.catb.org/~esr/faqs/smart-questions.html
http://www.caliburn.nl/topposting.html
http://www.netmeister.org/news/learn2quote.html


 
Reply With Quote
 
Robert Gamble
Guest
Posts: n/a
 
      05-21-2005
On Sat, 21 May 2005 05:23:39 +0000, CBFalconer wrote:

> Robert Gamble wrote:
>> On Fri, 20 May 2005 17:54:45 +0000, CBFalconer wrote:
>>> tigervamp wrote:
>>>

> ... snip ...
>>>>
>>>> No, the behavior is well defined by the Standard, see section
>>>> 7.20.3 of C99, I don't have a C89 copy handy.
>>>
>>> No, I don't consider it well defined. It leaves too much up to
>>> the implementation in the case of zero block size requests.

>>
>> I was referring specifically to the behavior of realloc
>> deallocating the original object which is well defined.
>>
>>> This means that NULL is not always a sign of failure, and that
>>> a non-NULL return is not necessarily freeable or reallocable.

>>
>> NULL is always a sign of failure when the size provided is
>> non-zero, if you want to provide a size of zero is is easy
>> enough to handle the return
>>
>> What evidence do you have that a non-NULL value returned by
>> realloc, when provided a size of zero, cannot safely be passed
>> to free() or realloc()?

>
> As I read the following from N869:
>
> 7.20.3 Memory management functions
>
> [#1] The order and contiguity of storage allocated by
> successive calls to the calloc, malloc, and realloc
> functions is unspecified. The pointer returned if the
> allocation succeeds is suitably aligned so that it may be
> assigned to a pointer to any type of object and then used to
> access such an object or an array of such objects in the
> space allocated (until the space is explicitly freed or
> reallocated). Each such allocation shall yield a pointer to
> an object disjoint from any other object. The pointer
> returned points to the start (lowest byte address) of the
> allocated space. If the space cannot be allocated, a null
> pointer is returned. If the size of the space requested is
> zero, the behavior is implementation-defined: either a null
>
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^
> pointer is returned, or the behavior is as if the size were
> some nonzero value, except that the returned pointer shall
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> not be used to access an object. The value of a pointer
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> that refers to freed space is indeterminate.
>
> Is freeing NULL so generated accessing an object?


No.

> Is freeing non-NULL so generated accessing an object?


No.

> When things are buried in layers of code we can easily guarantee
> that the pointer was created by malloc/realloc, and we can even
> guard it by making it NULL after passing to free, but that guard won't
> work if realloc can return a non-freeable pointer.


The pointer returned by calloc/malloc/realloc in any scenerio can always
be passed to free() at least once (only once for non-NULL).

From 7.20.3.2p2, free description:

"The free function causes the space pointed to by ptr to be deallocated,
that is, made available for further allocation. If ptr is a null pointer,
no action occurs. Otherwise, if the argument does not match a pointer
earlier returned by the calloc, malloc, or realloc function, or if the
space has been deallocated by a call to free or realloc, the behavior is
undefined."

According to the description, any pointer returned by calloc, malloc or
realloc that has not already been freed may be passed to free() without
invoking undefined behavior. No special provisions are made for the case
where zero size was passed to the allocation function to generate the
pointer in question.

To further support this position, section 7.20.3 of the Rationale
v5.10 provides the following example:

"The treatment of null pointers and zero-length allocation requests in the
definition of these functions was in part guided by a desire to support
this paradigm:

OBJ * p; // pointer to a variable list of OBJs
/* initial allocation */
p = (OBJ *) calloc(0, sizeof(OBJ));
/* ... */
/* reallocations until size settles */
while(1) {
p = (OBJ *) realloc((void *)p, c * sizeof(OBJ));
/* change value of c or break out of loop */
}
"

In this example, p is assigned the return value of calloc which, since one
of the arguments is zero, according to Standard behaves the same as if
malloc were passed a size of zero. p is now either NULL, or non-NULL
depending on the implementation (or possibly NULL if an error occured).
The value of p is then passed to realloc to increase the size, initially
from zero. If p was NULL from the calloc call, realloc will behave like
malloc. If calloc returned non-NULL, that value is now being passed to
realloc which deallocates the original zero-length object (as free would
do) and allocates more memory, etc.

In short, if an implmentation can "allocate" zero-length objects, it can
also free/realloc them. The effort needed to handle the implementation
defined part seems minimal.

Rob Gamble
 
Reply With Quote
 
Michael Mair
Guest
Posts: n/a
 
      05-21-2005
CBFalconer wrote:
> "S.Tobias" wrote:
>
>>CBFalconer <(E-Mail Removed)> wrote earlier:
>>
>>>In my nmalloc implementation for DJGPP I have chosen to treat a
>>>zero block size as a request for one byte, and let the alignment
>>>mechanisms raise it as they will.

>>
>>I'm not criticizing this, there're good reasons to do it like that,
>>but the Standard does not require the allocated object to have
>>alignment more than its size, right? Subsequent `malloc(1)'-s
>>could return ptrs that differ by 1 byte, right? (I'm asking
>>because the Std is a bit unclear there, IMHO.)

>
> No, that can't happen. Any non NULL return from
> malloc/calloc/realloc must be suitably aligned for any object
> whatsoever.


Can you provide chapter and verse, please?
This seems to be an unnecessary restriction -- why should malloc()
return 16-byte aligned memory for a 3-byte request if the
implementation "knows" that this implies a necessity for, say,
2-byte alignment _at_most_?

Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
 
Reply With Quote
 
Russell Shaw
Guest
Posts: n/a
 
      05-21-2005
CBFalconer wrote:
> "S.Tobias" wrote:
>
>>CBFalconer <(E-Mail Removed)> wrote earlier:
>>
>>
>>>In my nmalloc implementation for DJGPP I have chosen to treat a
>>>zero block size as a request for one byte, and let the alignment
>>>mechanisms raise it as they will.

>>
>>I'm not criticizing this, there're good reasons to do it like that,
>>but the Standard does not require the allocated object to have
>>alignment more than its size, right? Subsequent `malloc(1)'-s
>>could return ptrs that differ by 1 byte, right? (I'm asking
>>because the Std is a bit unclear there, IMHO.)

>
> No, that can't happen. Any non NULL return from
> malloc/calloc/realloc must be suitably aligned for any object
> whatsoever.


I'm writing a malloc thing and compiling it in gcc on a pc.
How do you know what the alignment should be?
 
Reply With Quote
 
Robert Gamble
Guest
Posts: n/a
 
      05-21-2005
On Sat, 21 May 2005 16:38:51 +0200, Michael Mair wrote:

> CBFalconer wrote:
>> "S.Tobias" wrote:
>>
>>>CBFalconer <(E-Mail Removed)> wrote earlier:
>>>
>>>>In my nmalloc implementation for DJGPP I have chosen to treat a zero
>>>>block size as a request for one byte, and let the alignment mechanisms
>>>>raise it as they will.
>>>
>>>I'm not criticizing this, there're good reasons to do it like that, but
>>>the Standard does not require the allocated object to have alignment
>>>more than its size, right? Subsequent `malloc(1)'-s could return ptrs
>>>that differ by 1 byte, right? (I'm asking because the Std is a bit
>>>unclear there, IMHO.)

>>
>> No, that can't happen. Any non NULL return from malloc/calloc/realloc
>> must be suitably aligned for any object whatsoever.

>
> Can you provide chapter and verse, please?


7.20.3p1 sentence 2:

"The pointer returned if the allocation succeeds is suitably aligned so
that it may be assigned to a pointer to any type of object and then used
to access such an object or an array of such objects in the space
allocated (until the space is explicitly deallocated)."

> This seems to be an unnecessary restriction -- why should malloc()
> return 16-byte aligned memory for a 3-byte request if the implementation
> "knows" that this implies a necessity for, say, 2-byte alignment
> _at_most_?


I'm not sure why, the Rationale doesn't give any hints here. It doesn't
particularly make sense that the allocated space must be aligned to
store an object that could not fit into the space, perhaps there is
another reason we are overlooking or maybe I'm misinterpreting the above
quote.

> Cheers
> Michael


Rob Gamble
 
Reply With Quote
 
S.Tobias
Guest
Posts: n/a
 
      05-21-2005
Robert Gamble <(E-Mail Removed)> wrote:
> On Sat, 21 May 2005 16:38:51 +0200, Michael Mair wrote:
> > CBFalconer wrote:
> >> "S.Tobias" wrote:


> >>>the Standard does not require the allocated object to have alignment
> >>>more than its size, right? Subsequent `malloc(1)'-s could return ptrs
> >>>that differ by 1 byte, right? (I'm asking because the Std is a bit
> >>>unclear there, IMHO.)
> >>
> >> No, that can't happen. Any non NULL return from malloc/calloc/realloc
> >> must be suitably aligned for any object whatsoever.

> >
> > Can you provide chapter and verse, please?


> 7.20.3p1 sentence 2:


> "The pointer returned if the allocation succeeds is suitably aligned so
> that it may be assigned to a pointer to any type of object and then used
> to access such an object or an array of such objects in the space
> allocated (until the space is explicitly deallocated)."


My interpretation of this is that the word "object" refers to
the allocated object, and "any type of object" means any type
that *this* object can have, although I think it is very unclear.
Without such interpretation the second part of the sentence
would not make sense (unless we accept that malloc(1) returns
an object suitable for any type - SIZE_MAX bytes at least).

--
Stan Tobias
mailx `echo (E-Mail Removed)LID | sed s/[[:upper:]]//g`
 
Reply With Quote
 
Dave Vandervies
Guest
Posts: n/a
 
      05-21-2005
In article <(E-Mail Removed)>,
Russell Shaw <rjshawN_o@s_pam.netspace.net.au> wrote:

>I'm writing a malloc thing and compiling it in gcc on a pc.
>How do you know what the alignment should be?


Compiler magic.

(This is something that the implementation needs to know (not just
for malloc; it will be needed anywhere it creates an object that may
have alignment restrictions), but it's not exposed to the programmer,
at least not without going beyond what the standard defines.)


dave

--
Dave Vandervies (E-Mail Removed)
Google seems to think that "united kingdom" should be under the category
of "Mature Content". this doesn't reflect well on either Google or the UK,
though i'm not sure which --Mike Burrell in comp.lang.c
 
Reply With Quote
 
Chris Torek
Guest
Posts: n/a
 
      05-21-2005
>CBFalconer wrote:
>>... Any non NULL return from malloc/calloc/realloc must be
>>suitably aligned for any object whatsoever.


In article <(E-Mail Removed)>
Michael Mair <(E-Mail Removed)> wrote:
>Can you provide chapter and verse, please?
>This seems to be an unnecessary restriction -- why should malloc()
>return 16-byte aligned memory for a 3-byte request if the
>implementation "knows" that this implies a necessity for, say,
>2-byte alignment _at_most_?


Indeed, it does seem unnecessary. It also seems to be what the
Standard requires. I suspect, however, that an implementor might
be able to get away with the "as-if" rule and align to just 2 bytes
in this case, provided the following code fragment still works:

void *vp;
char *cp;
double *dp;
/* add other types if desired */

cp = malloc(3);
if (cp == NULL) ... handle error ...
vp = cp;
dp = vp;
assert(vp == cp);
assert(dp == vp);
cp = (char *)dp;
assert(cp == vp);
puts("all OK");

In other words, if we have a system on which we can detect "failure
to align for any object whatsoever" by just using ordinary pointer
assignments, *then* that system will have to do 16-byte (or whatever)
alignment for a 3-byte malloc; but if the system handles "misaligned"
pointers without trouble, as long as they are not used to access
their misaligned objects, then -- because there will be no way for
the user to tell -- the as-if rule will allow us to implement
malloc(3) with just two-byte alignment.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Implicit localization Progman ASP .Net 2 03-02-2006 08:06 PM
Implicit rule PIX Nieuws Xs4all Cisco 3 11-30-2005 02:14 AM
Implicit object creation RHC Java 3 11-10-2004 09:22 AM
Passing implicit (standard) "config" object from jsp to java class (not servlet) cvelusc Java 5 06-03-2004 04:14 PM
Question on additional decimals in implicit conversion Jacob Java 7 10-03-2003 10:23 PM



Advertisments