By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,619 Members | 3,089 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,619 IT Pros & Developers. It's quick & easy.

realloc() implicit free() ?

P: n/a
If realloc() finds it necessary to move the memory block, then
does it free() the previously allocated block?

The C89 standard has some reference to undefined behaviour if one
realloc()'s memory that was freed by realloc(), but the only way
explicitly mentioned in the C89 standard to free memory via realloc()
is to realloc() it down to 0 bytes.

I had always assumed it would automatically free the previous memory,
but is the behaviour instead undefined [or defined as not happening] ?
--
"This was a Golden Age, a time of high adventure, rich living and
hard dying... but nobody thought so." -- Alfred Bester, TSMD
Nov 14 '05 #1
Share this Question
Share on Google+
86 Replies


P: n/a
Walter Roberson wrote:
If realloc() finds it necessary to move the memory block, then
does it free() the previously allocated block?
Yes.
The C89 standard has some reference to undefined behaviour if one
realloc()'s memory that was freed by realloc(), but the only way
explicitly mentioned in the C89 standard to free memory via realloc()
is to realloc() it down to 0 bytes.
Passing a pointer to realloc that points to memory free'd by _any_
function results in undefined behavior. If you successfully realloc
memory which results in the original object being deallocated, you must
provide a pointer to the new object created by realloc in subsequent
realloc calls as the old object has been freed.
I had always assumed it would automatically free the previous memory,
but is the behaviour instead undefined [or defined as not happening] ?

No, the behavior is well defined by the Standard, see section 7.20.3 of
C99, I don't have a C89 copy handy.
--
"This was a Golden Age, a time of high adventure, rich living and
hard dying... but nobody thought so." -- Alfred Bester, TSMD


Rob Gamble

Nov 14 '05 #2

P: n/a
In article <d6**********@canopus.cc.umanitoba.ca>,
Walter Roberson <ro******@ibd.nrc-cnrc.gc.ca> wrote:
If realloc() finds it necessary to move the memory block, then
does it free() the previously allocated block?
Quoth n869 (7.20.3.4):

[#2] The realloc function deallocates the old object pointed |
^^^^^^^^^^^^^^^^^^^^^^^^^^
to by ptr and returns a pointer to a new object that has the |
size specified by size. The contents of the new object |
shall be the same as that of the old object prior to |
deallocation, up to the lesser of the new and old sizes. |
Any bytes in the new object beyond the size of the old |
object have indeterminate values. |

[#4] The realloc function returns a pointer to the new |
object (which may have the same value as a pointer to the |
^^^^^^^^^^^^^^^^^^^^^^^^
old object), or a null pointer if the new object could not |
be allocated.

So the old one always gets (conceptually) freed, though in practice it's
Highly Unlikely that you'll get a non-moving call to realloc actually
freeing anything (this is an excellent example of the as-if rule).

The C89 standard has some reference to undefined behaviour if one
realloc()'s memory that was freed by realloc(), but the only way
explicitly mentioned in the C89 standard to free memory via realloc()
is to realloc() it down to 0 bytes.
The C89 draft I have here describes the same behavior, but it's less
clear that if the memory block fgets moved the old memory is deallocated.

I had always assumed it would automatically free the previous memory,
but is the behaviour instead undefined [or defined as not happening] ?


a call to realloc can do one of three things:
-fail to resize the memory block and return NULL without deallocating
the old one
-resize the block in-place and return the same pointer you gave it
-resize-and-move the block with behavior equivalent to doing malloc-
memcpy-free yourself (except that the old and new blocks are allowed
to overlap - I don't know if there's any reasonable way to implement
it that actually would overlap them) and return a pointer to the new
memory block

None of these involve leaving old memory blocks unfree()d.
dave

--
Dave Vandervies dj******@csclub.uwaterloo.ca

I believe you have misspelled "painfully stupid" at the end of this sentence.
--Peter Seebach in comp.lang.c
Nov 14 '05 #3

P: n/a


Walter Roberson wrote:
If realloc() finds it necessary to move the memory block, then
does it free() the previously allocated block?
Yes. (Well, it might not actually call free(), but
the outcome will be the same.) C99 7.20.3.4/2:

The realloc function deallocates the old object [...]
The C89 standard has some reference to undefined behaviour if one
realloc()'s memory that was freed by realloc(), but the only way
explicitly mentioned in the C89 standard to free memory via realloc()
is to realloc() it down to 0 bytes.
C89's language isn't as explicit, but throughout section
4.3.2 it keeps mentioning realloc() as one of the ways memory
can be deallocated, and in 4.10.3.4 it describes realloc() as
returning a pointer to the "possibly moved" memory. I think
the only reasonable reading of "moved" involves deallocation
of the previously-occupied space.
I had always assumed it would automatically free the previous memory,
but is the behaviour instead undefined [or defined as not happening] ?


A proper realloc() call can't invoke undefined behavior.
Even if C89 could be construed as not requiring the old memory
to be released, the behavior wouldn't be undefined -- you can't
refer to that old memory or to any pointer to it without invoking
undefined behavior, but simply leaking it isn't U.B. At worst
it'd be a QoI issue, with any implementation that leaked the
memory exhibiting negative QoI ...

--
Er*********@sun.com

Nov 14 '05 #4

P: n/a
In article <d6**********@news1brm.Central.Sun.COM>,
Eric Sosman <er*********@sun.com> wrote:
Walter Roberson wrote:
If realloc() finds it necessary to move the memory block, then
does it free() the previously allocated block?
Yes. C89's language isn't as explicit,


Thanks, everyone; and thanks for recognizing that C89 isn't precise
on the point.
--
'ignorandus (Latin): "deserving not to be known"'
-- Journal of Self-Referentialism
Nov 14 '05 #5

P: n/a
ro******@ibd.nrc-cnrc.gc.ca (Walter Roberson) wrote:
# If realloc() finds it necessary to move the memory block, then
# does it free() the previously allocated block?

You're over-specifying the function. What happens to the block is irrelevant
to understanding the function. Use the address returned by realloc; don't
worry about what it was before.

# I had always assumed it would automatically free the previous memory,
# but is the behaviour instead undefined [or defined as not happening] ?

I did a debugging realloc that left the original block alone so that it could
dump an allocation history. There could be all kinds of exotic things happenning
to the previous memory: that's why you shouldn't concern yourself with it.

--
SM Ryan http://www.rawbw.com/~wyrmwif/
Elvis was an artist. But that didn't stop him from joining the service
in time of war. That's why he is the king, and you're a shmuck.
Nov 14 '05 #6

P: n/a
tigervamp wrote:
Walter Roberson wrote:
If realloc() finds it necessary to move the memory block, then
does it free() the previously allocated block?


Yes.
The C89 standard has some reference to undefined behaviour if
one realloc()'s memory that was freed by realloc(), but the only
way explicitly mentioned in the C89 standard to free memory via
realloc() is to realloc() it down to 0 bytes.


Passing a pointer to realloc that points to memory free'd by _any_
function results in undefined behavior. If you successfully
realloc memory which results in the original object being
deallocated, you must provide a pointer to the new object created
by realloc in subsequent realloc calls as the old object has been
freed.
I had always assumed it would automatically free the previous
memory, but is the behaviour instead undefined [or defined as
not happening] ?


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. This means
that NULL is not always a sign of failure, and that a non-NULL
return is not necessarily freeable or reallocable.

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. This ensures that all successful
requests return a non-NULL pointer that can safely be used in
subsequent frees or reallocs. (It also has the convenient to me
side effect of ensuring space for some record-keeping in my code)

I suspect the standard is written to not invalidate the sloppier
malloc implementations already out there. In cases like this I
think it should include a recommended practice.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
Nov 14 '05 #7

P: n/a
In article <11*************@corp.supernews.com>,
SM Ryan <wy*****@tango-sierra-oscar-foxtrot-tango.fake.org> wrote:
ro******@ibd.nrc-cnrc.gc.ca (Walter Roberson) wrote:
# If realloc() finds it necessary to move the memory block, then
# does it free() the previously allocated block? You're over-specifying the function. What happens to the block is irrelevant
to understanding the function. Use the address returned by realloc; don't
worry about what it was before.


The question is not over-specified if one is concerned about
whether one is leaking memory. When your datasets are ~1 Gb each
and you are handling them in a loop, you can't afford to allow memory
to leak.
--
'ignorandus (Latin): "deserving not to be known"'
-- Journal of Self-Referentialism
Nov 14 '05 #8

P: n/a
ro******@ibd.nrc-cnrc.gc.ca (Walter Roberson) wrote:
# In article <11*************@corp.supernews.com>,
# SM Ryan <wy*****@tango-sierra-oscar-foxtrot-tango.fake.org> wrote:
# >ro******@ibd.nrc-cnrc.gc.ca (Walter Roberson) wrote:
# ># If realloc() finds it necessary to move the memory block, then
# ># does it free() the previously allocated block?
#
# >You're over-specifying the function. What happens to the block is irrelevant
# >to understanding the function. Use the address returned by realloc; don't
# >worry about what it was before.
#
# The question is not over-specified if one is concerned about
# whether one is leaking memory. When your datasets are ~1 Gb each
# and you are handling them in a loop, you can't afford to allow memory
# to leak.

All you can do to prevent leaks is to match frees to allocs; you don't need to
know how the library is implemented to do that much. It's still leaking
you're stuck unless you can get the library source code.

--
SM Ryan http://www.rawbw.com/~wyrmwif/
God's a skeeball fanatic.
Nov 14 '05 #9

P: n/a
On Fri, 20 May 2005 17:54:45 +0000, CBFalconer wrote:
tigervamp wrote:
Walter Roberson wrote:
If realloc() finds it necessary to move the memory block, then
does it free() the previously allocated block?
Yes.
The C89 standard has some reference to undefined behaviour if
one realloc()'s memory that was freed by realloc(), but the only
way explicitly mentioned in the C89 standard to free memory via
realloc() is to realloc() it down to 0 bytes.


Passing a pointer to realloc that points to memory free'd by _any_
function results in undefined behavior. If you successfully
realloc memory which results in the original object being
deallocated, you must provide a pointer to the new object created
by realloc in subsequent realloc calls as the old object has been
freed.
I had always assumed it would automatically free the previous
memory, but is the behaviour instead undefined [or defined as
not happening] ?


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()?

Rob Gamble
Nov 14 '05 #10

P: n/a
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
Nov 14 '05 #11

P: n/a
CBFalconer <cb********@yahoo.com> 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 <cb********@yahoo.com> 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 si***@FamOuS.BedBuG.pAlS.INVALID | sed s/[[:upper:]]//g`
Nov 14 '05 #12

P: n/a
"S.Tobias" wrote:
CBFalconer <cb********@yahoo.com> 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
Nov 14 '05 #13

P: n/a
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
Nov 14 '05 #14

P: n/a
CBFalconer wrote:
"S.Tobias" wrote:
CBFalconer <cb********@yahoo.com> 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.
Nov 14 '05 #15

P: n/a
CBFalconer wrote:
"S.Tobias" wrote:
CBFalconer <cb********@yahoo.com> 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?
Nov 14 '05 #16

P: n/a
On Sat, 21 May 2005 16:38:51 +0200, Michael Mair wrote:
CBFalconer wrote:
"S.Tobias" wrote:
CBFalconer <cb********@yahoo.com> 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
Nov 14 '05 #17

P: n/a
Robert Gamble <rg*******@gmail.com> 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 si***@FamOuS.BedBuG.pAlS.INVALID | sed s/[[:upper:]]//g`
Nov 14 '05 #18

P: n/a
In article <1d************@main.anatron.com.au>,
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 dj******@csclub.uwaterloo.ca
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
Nov 14 '05 #19

P: n/a
>CBFalconer wrote:
... Any non NULL return from malloc/calloc/realloc must be
suitably aligned for any object whatsoever.

In article <3f************@individual.net>
Michael Mair <Mi**********@invalid.invalid> 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.
Nov 14 '05 #20

P: n/a
Robert Gamble wrote:
On Sat, 21 May 2005 16:38:51 +0200, Michael Mair wrote:
CBFalconer wrote:
"S.Tobias" wrote:
CBFalconer <cb********@yahoo.com> 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 usedto 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.


The malloc subsystem doesn't know, and can't know, what type the
pointer will be used for. It returns a void*, and the only
information it gets is the size required. That size may be for one
item, or for many items.

Similarly the application has no information as to the alignment
requirements for a type. The compiler system does. That is one of
the fundamental reasons that malloc is a system function, and
simply cannot be written in purely portable code.

--
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
Nov 14 '05 #21

P: n/a
Russell Shaw wrote:
CBFalconer wrote:
"S.Tobias" wrote:
CBFalconer <cb********@yahoo.com> 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?


No, and neither can you. Only the system implementor can know.
You can make some educated guesses in some cases, but you can never
find out in a portable manner.

--
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
Nov 14 '05 #22

P: n/a
CBFalconer wrote:
Robert Gamble wrote:
On Sat, 21 May 2005 16:38:51 +0200, Michael Mair wrote:
CBFalconer wrote:

"S.Tobias" wrote:

>CBFalconer <cb********@yahoo.com> 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 usedto access such an object or an array
of such objects in the space allocated (until the space is
explicitly deallocated)."
Thanks, Rob :-)
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.


The malloc subsystem doesn't know, and can't know, what type the
pointer will be used for. It returns a void*, and the only
information it gets is the size required. That size may be for one
item, or for many items.

Similarly the application has no information as to the alignment
requirements for a type. The compiler system does. That is one of
the fundamental reasons that malloc is a system function, and
simply cannot be written in purely portable code.


Hmmm, I can accept this as an additional explanation but still do
not see the _necessity_ for the standard giving the cited
restriction.
Thank you.

Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Nov 14 '05 #23

P: n/a
Chris Torek wrote:
CBFalconer wrote:
... Any non NULL return from malloc/calloc/realloc must be
suitably aligned for any object whatsoever.

In article <3f************@individual.net>
Michael Mair <Mi**********@invalid.invalid> 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.


Thank you -- as usual, I can learn something from your response :-)

Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Nov 14 '05 #24

P: n/a
Robert Gamble wrote:
On Sat, 21 May 2005 16:38:51 +0200, Michael Mair wrote:

CBFalconer wrote:
"S.Tobias" wrote:
CBFalconer <cb********@yahoo.com> 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)."


Taken in isolation, this sentence says that

struct s { char c[30000]; } x = { 0 };
struct s *p = malloc(1); /* assume success */
*p = x;

should work: The allocation has succeeded, the returned value
is therefore suitably aligned for any type (`struct s' in
particular), the value can be assigned to any type of pointer
(including `struct s*'), and can then be used to access an
object of that type. All the preconditions of the sentence
are met -- and yet, the access is obviously not permitted.

What this means is that snipping a sentence from the rest
of the Standard can distort its meaning. Elsewhere in the
Standard we can learn that `*p = x' produces undefined behavior,
so no conforming program can access a `struct s' through the
value returned by this particular malloc(). It follows that no
conforming program can actually encounter any alignment
problem by trying to access a `struct s' through this pointer;
the access itself is forbidden. Under the "as if" rule, if
nothing else, I believe malloc(1) can perfectly well return a
value that is not `struct s'-aligned because no conforming
program can ever detect the non-alignment.

However, the quoted sentence still places some restrictions
on what malloc(1) could return. For example,

void *p1 = malloc(1); /* assume success */
double *dp = p1;
void *p2 = dp;
assert (p2 == p1);

That is, converting the pointer to `double*' and back again
must not change its value. On machines where pointers to
different types have different representations, malloc(1) is
constrained to return values that can be converted to and from
any data pointer type without damage -- but as long as the
conversion is guaranteed to succeed, I don't think the value
need actually suffice for any data type that won't fit in the
allocated space.

--
Eric Sosman
es*****@acm-dot-org.invalid

Nov 14 '05 #25

P: n/a
In article <1d************@main.anatron.com.au>
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?


Alas, ANSI/ISO C does not have any way to find out.

In the absence of the ability to write "comp.lang.c-conformant" code,
if you still need to get the job done, write non-conformant code. :-)

For the various 4.xBSD systems, we defined a pair of macros (in
one of the <machine/*.h> headers), ALIGN(p) and ALIGNBYTES, that
do the trick.

The "machine" headers are different on each implementation, but
attempt to abstract out as much as possible. Thus, for instance,
<machine/frame.h> gives the stack frame for whatever implementation
you are using, always as a "struct frame" (and additional special
frames for user => kernel boundary crossings, in some cases). This
works fine as long as there is one consistent call-stack frame,
and you can write a simplified stack-trace-dump function that works
on (say) five completely different architectures (with some assistant
functions or macros), as long as they all use just the one "struct
frame". This eases code porting, but is not perfect: as soon as
you try to support (say) both 32- and 64-bit SPARC routines, you
start to need to distinguish between a 32-bit stack frame and a
64-bit stack frame ("struct frame32" and "struct frame64"), and
you must write a SPARC-specific "simplified stack-trace-dump"
module. Still, you get to share the original (single frame) dump
routine across those five machines, so that instead of six source
files to maintain (for six architectures), you have just two.

The idea is simple enough: make common code to solve common problems.
The trick is knowing what is common, what is not, and how to abstract
away irrelevant details without losing the important details. :-)
--
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.
Nov 14 '05 #26

P: n/a
On Sat, 21 May 2005 13:33:23 -0400, Eric Sosman wrote:
Robert Gamble wrote:
On Sat, 21 May 2005 16:38:51 +0200, Michael Mair wrote:

CBFalconer wrote:

"S.Tobias" wrote:
>CBFalconer <cb********@yahoo.com> 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)."


Taken in isolation, this sentence says that

struct s { char c[30000]; } x = { 0 };
struct s *p = malloc(1); /* assume success */
*p = x;

should work:


No, it doesn't.
The allocation has succeeded, the returned value is
therefore suitably aligned for any type (`struct s' in particular), the
value can be assigned to any type of pointer (including `struct s*'),
and can then be used to access an object of that type. All the
preconditions of the sentence are met -- and yet, the access is
obviously not permitted.


The only thing being discussed here is alignmentment requirements. The
above quote states that your object created with malloc will be properly
*aligned* to hold any type, not that any type can actually be stored in it
if the space doesn't exist.

Rob Gamble
Nov 14 '05 #27

P: n/a
Eric Sosman <es*****@acm-dot-org.invalid> wrote:
Robert Gamble wrote:
On Sat, 21 May 2005 16:38:51 +0200, Michael Mair wrote:
CBFalconer wrote: 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:
(1) "The pointer returned if the allocation succeeds is suitably aligned so
that it may be assigned to a pointer to any type of object (2)and then used
to access such an object or an array of such objects in the space
allocated (until the space is explicitly deallocated)."

Taken in isolation, this sentence says that struct s { char c[30000]; } x = { 0 };
struct s *p = malloc(1); /* assume success */
*p = x; should work: The allocation has succeeded, the returned value
is therefore suitably aligned for any type (`struct s' in
particular), the value can be assigned to any type of pointer
(including `struct s*'), and can then be used to access an
object of that type. All the preconditions of the sentence
are met -- and yet, the access is obviously not permitted. What this means is that snipping a sentence from the rest
of the Standard can distort its meaning. (3)Elsewhere in the
Standard we can learn that `*p = x' produces undefined behavior,
so no conforming program can access a `struct s' through the
value returned by this particular malloc().


[ snipped implications which follow from (1) and (3),
but somehow (2) was lost, because it didn't fit into the theory;
rejected only 30% of facts - congratulations of a success! ]

So, under your interpretation, the Standard in one place *requires*
something that it forbids at another, and yet you're happy about it?
What do you people drink to keep you out of depression?
How about this: I say the Standard requires `malloc(1)' to return
at least enough space to accommodate `struct s'.
Stretched? Yes, but fits your assumptions better.

In another post I offered a different interpretation of the Standard,
which IMHO is more rational (I mean the implications are more rational,
not the interpretation itself), but I won't argue for its credibility,
because I'm not completely convinced myself.

Yet another resolution could be to acknowledge the Standard has
simply an error there and no conclusions can be drawn.

--
Stan Tobias
mailx `echo si***@FamOuS.BedBuG.pAlS.INVALID | sed s/[[:upper:]]//g`
Nov 14 '05 #28

P: n/a
"Michael Mair" <Mi**********@invalid.invalid> wrote in message
news:3f************@individual.net...
CBFalconer wrote:
The malloc subsystem doesn't know, and can't know, what type the
pointer will be used for. It returns a void*, and the only
information it gets is the size required. That size may be for one
item, or for many items.

Similarly the application has no information as to the alignment
requirements for a type. The compiler system does. That is one of
the fundamental reasons that malloc is a system function, and
simply cannot be written in purely portable code.


Hmmm, I can accept this as an additional explanation but still do
not see the _necessity_ for the standard giving the cited
restriction.


If malloc() were allowed to inspect the size of the request and
determine that it was allowed to return a pointer to something of a
different alignment than normal, there would be nothing wrong with that
per se.

However, it is reasonable to assume that no existing implementation did
that at the time C89 was written, nor that any new implementation after
that time would take advantage of that "feature" since it'd be extra
work for virtually no gain, so why make a point of allowing it? Letting
malloc() deal with a single alignment for all requests, regardless of
size, is the simpler option.

S

--
Stephen Sprunk "Those people who think they know everything
CCIE #3723 are a great annoyance to those of us who do."
K5SSS --Isaac Asimov
Nov 14 '05 #29

P: n/a
In article <11*************@corp.supernews.com>,
SM Ryan <wy*****@tango-sierra-oscar-foxtrot-tango.fake.org> wrote:
# The question is not over-specified if one is concerned about
# whether one is leaking memory. When your datasets are ~1 Gb each
# and you are handling them in a loop, you can't afford to allow memory
# to leak. All you can do to prevent leaks is to match frees to allocs; you don't need to
know how the library is implemented to do that much. It's still leaking
you're stuck unless you can get the library source code.


That's not ALL you can do: you can also ask questions about paragraphs
that one might have overlooked or which might have been clarified
in addendums that one hasn't seen, which proscribe the behaviour
of library routines so as to remove the ambiguity.

If no-one happens to know the answer, or if the answer is
indeterminate, then one can sometimes write one's own routine that
avoids the indeterminate behaviour. In the case of realloc(),
since it is never -required- that the address be left unchanged,
one can write a replacement for realloc() in terms of malloc(),
a memory copy, and a free(), provided that one knows the current
size of the object at hand.
--
Entropy is the logarithm of probability -- Boltzmann
Nov 14 '05 #30

P: n/a
ro******@ibd.nrc-cnrc.gc.ca (Walter Roberson) wrote:

# That's not ALL you can do: you can also ask questions about paragraphs
# that one might have overlooked or which might have been clarified
# in addendums that one hasn't seen, which proscribe the behaviour
# of library routines so as to remove the ambiguity.

Do you have sample code of how to do that?

--
SM Ryan http://www.rawbw.com/~wyrmwif/
Why are we here?
whrp
Nov 14 '05 #31

P: n/a
Walter Roberson wrote:
In article <11*************@corp.supernews.com>,
SM Ryan <wy*****@tango-sierra-oscar-foxtrot-tango.fake.org> wrote:
# The question is not over-specified if one is concerned about
# whether one is leaking memory. When your datasets are ~1 Gb each
# and you are handling them in a loop, you can't afford to allow memory
# to leak.

All you can do to prevent leaks is to match frees to allocs; you don't need to
know how the library is implemented to do that much. It's still leaking
you're stuck unless you can get the library source code.


That's not ALL you can do: you can also ask questions about paragraphs
that one might have overlooked or which might have been clarified
in addendums that one hasn't seen, which proscribe the behaviour
of library routines so as to remove the ambiguity.

If no-one happens to know the answer, or if the answer is
indeterminate, then one can sometimes write one's own routine that
avoids the indeterminate behaviour. In the case of realloc(),
since it is never -required- that the address be left unchanged,
one can write a replacement for realloc() in terms of malloc(),
a memory copy, and a free(), provided that one knows the current
size of the object at hand.


For the address to not change, the new realloc'd size must fit in
the same place. If there was occupied memory following your data
and you wanted to increase the size of your data, the realloc will
have to copy it all to a different location where it will fit.
In this case, the address *will* change.
Nov 14 '05 #32

P: n/a
In article <11*************@corp.supernews.com>,
SM Ryan <wy*****@tango-sierra-oscar-foxtrot-tango.fake.org> wrote:
ro******@ibd.nrc-cnrc.gc.ca (Walter Roberson) wrote: # That's not ALL you can do: you can also ask questions about paragraphs
# that one might have overlooked or which might have been clarified
# in addendums that one hasn't seen, which proscribe the behaviour
# of library routines so as to remove the ambiguity. Do you have sample code of how to do that?


Sure, but are you finding a deficiency in your existing facility to ask
intelligent questions about matters whose resolutions are not immediately
clear?
--
"[...] it's all part of one's right to be publicly stupid." -- Dave Smey
Nov 14 '05 #33

P: n/a
S.Tobias <si***@famous.bedbug.pals.invalid> wrote:
Eric Sosman <es*****@acm-dot-org.invalid> wrote:

"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)."
Taken in isolation, this sentence says that struct s { char c[30000]; } x = { 0 };
struct s *p = malloc(1); /* assume success */
Just a thought:

There might actually be a reason to require `p' to have max alignment
(assignment-wise) for `malloc(0)'. It is even documented in
the Rationale:
OBJ *p = calloc(0, sizeof(OBJ));
The Standard obviously wants to support zero-length array paradigm,
although zero-size objects are not supported.

`malloc(1)' may be considered as "a zero-length array (of any type)
plus 1 byte ``padding'' ".
When you need a zero-length array, but at the same time you need
a unique pointer (and it is not known if malloc(0) returns NULL
or not), then malloc(1) (or generally: malloc(n*size+1), n==0,1,2,...)
will always provide such pointer.

Therefore we actually want `malloc(n)' to return for every `n' a value
that is aligned suitably for any type.
*p = x;


However I still can't see any reason to require max alignment
access-wise (more than the requested size), but maybe this is just
not to make things too complicated. The Standard could simply
say that the returned pointer value has maximum alignment, but
for strange reason it chose to say in a circuitous way that the
alignment is maximal both assignment-wise and access-wise (which
is exactly the same thing), forgetting that access itself is
not always possible.
[Sorry for being a little ironic last time.]

--
Stan Tobias
mailx `echo si***@FamOuS.BedBuG.pAlS.INVALID | sed s/[[:upper:]]//g`
Nov 14 '05 #34

P: n/a
In article <lo************@main.anatron.com.au>,
Russell Shaw <rjshawN_o@s_pam.netspace.net.au> wrote:
Walter Roberson wrote:
one can sometimes write one's own routine that
avoids the indeterminate behaviour. In the case of realloc(),
since it is never -required- that the address be left unchanged,
one can write a replacement for realloc() in terms of malloc(),
a memory copy, and a free(), provided that one knows the current
size of the object at hand.

For the address to not change, the new realloc'd size must fit in
the same place. If there was occupied memory following your data
and you wanted to increase the size of your data, the realloc will
have to copy it all to a different location where it will fit.
In this case, the address *will* change.


Yes? I must be missing your point? Or did you perchance overlook
my double negative? "never required [...] left unchanged" means
"the routine may change the address under any circumstances it
feels fit."

If one writes a replacement version of realloc() in terms of
malloc/copy/free (and an additional parameter that indicates
the object's -current- size), then what one loses is the
-possibility- that the data won't have to move (and thus
be copied) if extra space just happens to be available
immediately after to the current object. But that's an
efficiency optimization; and especially if one is working with
large data sets, the extra efficiency might be pretty meaningless
compared to the possibility that one is leaking large chunks
of memory if indeed realloc() does not free the original
memory chunk when it happens to move data.
My user was satisfied with the posted analysis that in C99 the
as-if free() is explicit, and that in C89 the as-if free() is the
most reasonable interpretation. My commentatary in this sub-thread
is only around the point of whether I should have been telling my user
"You shouldn't even be -thinking- about whether there might be a memory
leak or not: it is Not Allowed to ask questions even to yourself about
anything not explicitly made clear in the one paragraph of the standard
most directly dedicated to defining the routine."
--
Any sufficiently old bug becomes a feature.
Nov 14 '05 #35

P: n/a
Walter Roberson wrote:
In article <lo************@main.anatron.com.au>,
Russell Shaw <rjshawN_o@s_pam.netspace.net.au> wrote:
Walter Roberson wrote:
one can sometimes write one's own routine that
avoids the indeterminate behaviour. In the case of realloc(),
since it is never -required- that the address be left unchanged,
one can write a replacement for realloc() in terms of malloc(),
a memory copy, and a free(), provided that one knows the current
size of the object at hand.


For the address to not change, the new realloc'd size must fit in
the same place. If there was occupied memory following your data
and you wanted to increase the size of your data, the realloc will
have to copy it all to a different location where it will fit.
In this case, the address *will* change.

Yes? I must be missing your point? Or did you perchance overlook
my double negative? "never required [...] left unchanged" means
"the routine may change the address under any circumstances it
feels fit."


I saw the context of:

...one can write a replacement for realloc() in terms of malloc(),
memory copy, and a free(), provided that one knows the current
size of the object at hand.

combined with the context of the preceding part as meaning that
you could make it so that the returned address was never changed.
If one writes a replacement version of realloc() in terms of
malloc/copy/free (and an additional parameter that indicates
the object's -current- size), then what one loses is the
-possibility- that the data won't have to move
In other words, it *will* move. But not so. If the new size passed in
is smaller than the current size, you could just return the same address.
(and thus
be copied) if extra space just happens to be available
immediately after to the current object. But that's an
efficiency optimization; and especially if one is working with
large data sets, the extra efficiency might be pretty meaningless
compared to the possibility that one is leaking large chunks
of memory if indeed realloc() does not free the original
memory chunk when it happens to move data.
I know what you mean, but your double negatives are a bit confusing;)
My user was satisfied with the posted analysis that in C99 the
as-if free() is explicit, and that in C89 the as-if free() is the
most reasonable interpretation. My commentatary in this sub-thread
is only around the point of whether I should have been telling my user
"You shouldn't even be -thinking- about whether there might be a memory
leak or not: it is Not Allowed to ask questions even to yourself about
anything not explicitly made clear in the one paragraph of the standard
most directly dedicated to defining the routine."


ok
Nov 14 '05 #36

P: n/a
ro******@ibd.nrc-cnrc.gc.ca (Walter Roberson) wrote:
# In article <11*************@corp.supernews.com>,
# SM Ryan <wy*****@tango-sierra-oscar-foxtrot-tango.fake.org> wrote:
# >ro******@ibd.nrc-cnrc.gc.ca (Walter Roberson) wrote:
#
# ># That's not ALL you can do: you can also ask questions about paragraphs
# ># that one might have overlooked or which might have been clarified
# ># in addendums that one hasn't seen, which proscribe the behaviour
# ># of library routines so as to remove the ambiguity.
#
# >Do you have sample code of how to do that?
#
# Sure, but are you finding a deficiency in your existing facility to ask
# intelligent questions about matters whose resolutions are not immediately
# clear?

Simple 'no' would've sufficed.

Someday you'll learn about modular programming.

--
SM Ryan http://www.rawbw.com/~wyrmwif/
You face forward, or you face the possibility of shock and damage.
Nov 14 '05 #37

P: n/a
Eric Sosman wrote:
Robert Gamble wrote:

.... snip ...

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)."


Taken in isolation, this sentence says that

struct s { char c[30000]; } x = { 0 };
struct s *p = malloc(1); /* assume success */
*p = x;

should work: The allocation has succeeded, the returned value
is therefore suitably aligned for any type (`struct s' in
particular), the value can be assigned to any type of pointer
(including `struct s*'), and can then be used to access an
object of that type. All the preconditions of the sentence
are met -- and yet, the access is obviously not permitted.


However, if you follow that with:

if (tmp = realloc(p, sizeof *p) {
p = tmp;
*p = x;
}

access is perfectly legitimate, and p may not necessarily have
changed. The alignment is now needed.

--
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
Nov 14 '05 #38

P: n/a
"S.Tobias" wrote:
.... snip ...
How about this: I say the Standard requires `malloc(1)' to return
at least enough space to accommodate `struct s'.
Stretched? Yes, but fits your assumptions better.


No. malloc has no way of knowing what such a requirement is.

--
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
Nov 14 '05 #39

P: n/a
In article <11*************@corp.supernews.com>,
SM Ryan <wy*****@tango-sierra-oscar-foxtrot-tango.fake.org> wrote:
Someday you'll learn about modular programming.
My Magic 8-Ball seems to be out of order this evening; I don't
see how modular programming has to do with the question of whether
or not "all" one can do is interpret documentation narrowly and
at face value.

It seems to me that, in the absence of knowledge of whether
the as-if free() was or was not done, use of realloc() would
be contrary to Dijkstra's principles of structured programming
that routines should be -provably- correct. Code that leaks memory
(except at program exit) would seldom be "probably correct".

Someday you'll learn about modular programming.


A long time ago, in a galaxy far far away...
--
The rule of thumb for speed is:

1. If it doesn't work then speed doesn't matter. -- Christian Bau
Nov 14 '05 #40

P: n/a
CBFalconer <cb********@yahoo.com> wrote:
"S.Tobias" wrote:
... snip ...

How about this: I say the Standard requires `malloc(1)' to return
at least enough space to accommodate `struct s'.
Stretched? Yes, but fits your assumptions better.

No. malloc has no way of knowing what such a requirement is.


Of course not. It would have to return maximum object size.
There would have to be maximum object size.

--
Stan Tobias
mailx `echo si***@FamOuS.BedBuG.pAlS.INVALID | sed s/[[:upper:]]//g`
Nov 14 '05 #41

P: n/a
CBFalconer <cb********@yahoo.com> wrote:
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?


I should hope not. If it is, then

int *x;
x=malloc(100);
free(x);

invokes undefined behaviour. When the memory is received from malloc(),
it contains uninitialised bytes; it never is given a real value;
therefore, accessing it is accessing an uninitialised int value, which
invokes UB (may be a trap representation). Therefore, if free() accessed
the object its argument points at, that code would possibly access a
trap representation. But TTBOMK, it's valid code. Because of this, I
conclude that so is

int *x;
x=malloc(0);
free(x);

since free() doesn't access *x in this case, either.

Richard
Nov 14 '05 #42

P: n/a
SM Ryan <wy*****@tango-sierra-oscar-foxtrot-tango.fake.org> wrote:

[ Learn to quote, damn it. ]
ro******@ibd.nrc-cnrc.gc.ca (Walter Roberson) wrote:
# In article <11*************@corp.supernews.com>,
# SM Ryan <wy*****@tango-sierra-oscar-foxtrot-tango.fake.org> wrote:
# >ro******@ibd.nrc-cnrc.gc.ca (Walter Roberson) wrote:
# ># If realloc() finds it necessary to move the memory block, then
# ># does it free() the previously allocated block?
#
# >You're over-specifying the function. What happens to the block is irrelevant
# >to understanding the function. Use the address returned by realloc; don't
# >worry about what it was before.
#
# The question is not over-specified if one is concerned about
# whether one is leaking memory. When your datasets are ~1 Gb each
# and you are handling them in a loop, you can't afford to allow memory
# to leak.

All you can do to prevent leaks is to match frees to allocs; you don't need to
know how the library is implemented to do that much. It's still leaking
you're stuck unless you can get the library source code.


Nope; that's probably why the OP wanted to know whether realloc() frees
the block it is passed. If it didn't, and could leak, one could still
implement a version which doesn't leak using malloc() and free(). From
the answers to the OP one can conclude that this isn't necessary; but
the question makes sense.

Richard
Nov 14 '05 #43

P: n/a
On 21 May 2005 16:40:23 GMT, Chris Torek
<no****@torek.net> wrote:
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.


Is there anything which says that alignments are always on a power of 2?
If not, then malloc() could have to be very wasteful. Imagine a system
(the DS9011, say) where a byte is 11 bits and the sizes (and alignments)
in bytes are:

Type Alignment
char 1
short 2
int 3
long 5
long long 7

and assigning

Thus malloc() would have to return an area aligned to at least 2*3*5*7
which is 210 bytes, even for malloc(1).

Perhaps it is needed a version of malloc() which takes the size of the
base object as well as the number of them, so

type *p = nmalloc(sizeof(*p), num);

That could look up the size and work out the alignment (if it was not a
basic type then it could just use the sizeof value, since the alignment
for that type must be that value or a submultiple of it).

Chris C
Nov 14 '05 #44

P: n/a
# > # ># If realloc() finds it necessary to move the memory block, then
# > # ># does it free() the previously allocated block?

# Nope; that's probably why the OP wanted to know whether realloc() frees
# the block it is passed. If it didn't, and could leak, one could still
# implement a version which doesn't leak using malloc() and free(). From
# the answers to the OP one can conclude that this isn't necessary; but
# the question makes sense.

Some day you'll learn about modular programming. Most malloc libraries promise
not to leak if you match allocates and free properly. So with modular programming
you concentrate on the interface (matching allocates and frees) and not worry
about how the other modules fulfills its promises.

It suffices to know the interface and that you cannot trust the input pointer
to realloc, but rather the output pointer (whether they differ or no).

Trying to figure out if realloc calls free or immediately deallocates or unmaps
pages or anything else is breaking into the module without need. Even worrying
about whether memory moves is irrelevant. Suppose realloc is able to remap a
page so the phyical DRAM appears at a different address. Was memory moved or
not? MU.

--
SM Ryan http://www.rawbw.com/~wyrmwif/
The little stoner's got a point.
Nov 14 '05 #45

P: n/a
SM Ryan wrote:
# > # ># If realloc() finds it necessary to move the memory block, then # > # ># does it free() the previously allocated block?

# Nope; that's probably why the OP wanted to know whether realloc() frees # the block it is passed. If it didn't, and could leak, one could still # implement a version which doesn't leak using malloc() and free(). From # the answers to the OP one can conclude that this isn't necessary; but # the question makes sense.

Some day you'll learn about modular programming. Most malloc libraries promise not to leak if you match allocates and free properly. So with modular programming you concentrate on the interface (matching allocates and frees) and not worry about how the other modules fulfills its promises.
You have completely missed the point numerious times in this thread
with your remarks so let me spell it out for you: The OP was asking
about the "promises" of the "interface" provided by the Standard. It
was a completely valid question, you cannot properly use the function
in question without knowing the answer. Either realloc frees memory or
it doesn't. If it doesn't then you must free it yourself in specific
scenerios or introduce a memory leak. If is does, then attempting to
free the memory yourself would lead to undefined behavior. Try to
understand this before you post again.
It suffices to know the interface and that you cannot trust the input pointer to realloc, but rather the output pointer (whether they differ or no).
Trying to figure out if realloc calls free or immediately deallocates or unmaps pages or anything else is breaking into the module without need. Even worrying about whether memory moves is irrelevant. Suppose realloc is able to remap a page so the phyical DRAM appears at a different address. Was memory moved or not? MU.

--
SM Ryan http://www.rawbw.com/~wyrmwif/
The little stoner's got a point.


Rob Gamble

Nov 14 '05 #46

P: n/a
# > # > # ># If realloc() finds it necessary to move the memory block,
# then
# > # > # ># does it free() the previously allocated block?

# You have completely missed the point numerious times in this thread
# with your remarks so let me spell it out for you: The OP was asking
# about the "promises" of the "interface" provided by the Standard. It

Read the quoted question, clemclone.
does it free() the previously allocated block?
That's a question about the implementation of realloc not the interface.
In modular programming you don't worry about what realloc does. You only
worry about the interface. The interface has two important points on
realloc:

If you match allocates and frees, most mallocs promise not
to leak.

Use the output pointer of realloc and no longer the input.

Follow these a few other interface rules and and you don't have to
worry whether realloc calls free() or sbrk() or mapin() or anything
else.

# was a completely valid question, you cannot properly use the function
# in question without knowing the answer. Either realloc frees memory or
# it doesn't. If it doesn't then you must free it yourself in specific

You're not programming modularly if you need to know how realloc works.
For me it is sufficient to know that if I match frees with allocates
and use the current block pointers, the library promises to reuse memory
eventually. How and when are irrelevant to me.

# scenerios or introduce a memory leak. If is does, then attempting to
# free the memory yourself would lead to undefined behavior. Try to
# understand this before you post again.

Knowing the interface does not require knowing whether realloc calls
free(). I really don't care if realloc calls free. What I care about
is when I call free(), everything back to the original malloc or
realloc will be recycled.

--
SM Ryan http://www.rawbw.com/~wyrmwif/
Title does not dictate behaviour.
Nov 14 '05 #47

P: n/a
Richard Bos <rl*@hoekstra-uitgeverij.nl> wrote:
CBFalconer <cb********@yahoo.com> wrote:
Is freeing NULL so generated accessing an object? Is freeing
non-NULL so generated accessing an object?

I should hope not. If it is, then int *x;
x=malloc(100);
free(x); invokes undefined behaviour. When the memory is received from malloc(),
it contains uninitialised bytes; it never is given a real value;
therefore, accessing it is accessing an uninitialised int value, which
invokes UB


But free could write the object, which also counts as an access.

But anyway, I think that everybody now agrees that free() does not
access anything.

--
Stan Tobias
mailx `echo si***@FamOuS.BedBuG.pAlS.INVALID | sed s/[[:upper:]]//g`
Nov 14 '05 #48

P: n/a
In article <pa****************************@gmail.com>,
Robert Gamble <rg*******@gmail.com> wrote:
The only thing being discussed here is alignmentment requirements. The
above quote states that your object created with malloc will be properly
*aligned* to hold any type, not that any type can actually be stored in it
if the space doesn't exist.


But no conforming program can tell the difference, so the statement
places no constraint on implementations.

-- Richard
Nov 14 '05 #49

P: n/a
Chris Croughton wrote:

Is there anything which says that alignments are always on a power of 2?
Not to my knowledge.
If not, then malloc() could have to be very wasteful. Imagine a system
(the DS9011, say) where a byte is 11 bits and the sizes (and alignments)
in bytes are:

Type Alignment
char 1
short 2
int 3
long 5
long long 7

and assigning

Thus malloc() would have to return an area aligned to at least 2*3*5*7
which is 210 bytes, even for malloc(1).
ITYM "1*2*3*5*7." Two marks off for bad penmanship.
Perhaps it is needed a version of malloc() which takes the size of the
base object as well as the number of them, so

type *p = nmalloc(sizeof(*p), num);

That could look up the size and work out the alignment (if it was not a
basic type then it could just use the sizeof value, since the alignment
for that type must be that value or a submultiple of it).


About a decade ago this question arose with respect to
calloc(), and the eventual conclusion was that calloc() had to
be "oblivious" to the significance of its two operands. That
is, calloc(2,8) and calloc(8,2) had to satisfy exactly the same
alignment constraints: the former could not legitimately decide
that only 2-byte alignment was required.

Mind you, much heated discussion preceded the conclusion,
and it is not certain that all the discussors agreed thereto.
"A man convinced against his will is of the same opinion still."

--
Eric Sosman
es*****@acm-dot-org.invalid
Nov 14 '05 #50

86 Replies

This discussion thread is closed

Replies have been disabled for this discussion.