when can realloc fail?

N

Nelu

pete said:
malloc can't be successful in allocating space
and still return NULL.

Why not? 7.20.3 only says that the functions return NULL if space
for the object could not be allocated. It doesn't say anything
about successful allocation. I understand the fact returning NULL
on successful allocations will lead to memory leaks, probably,
but I couldn't find anything related to that in the standard.
 
P

pete

Nelu said:
pete wrote:

Why not? 7.20.3 only says that the functions return NULL if space
for the object could not be allocated. It doesn't say anything
about successful allocation.

Read harder!

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.
 
N

Nelu

pete said:
Read harder!

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.

I read those lines but I think I misunderstood them. I was
thinking that NULL satisfies the conditions but "... 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)" shows I was wrong about this.

Thanks!
 
C

CBFalconer

Eric said:
Could you point out where this is allowed? I can see
that it's permitted for realloc(NULL, 0), but can't find any
such dispensation for realloc(p, 0) where p!=NULL.

Penultimate sentence.

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.
 
J

Joe Wright

CBFalconer said:
Eric said:
Could you point out where this is allowed? I can see
that it's permitted for realloc(NULL, 0), but can't find any
such dispensation for realloc(p, 0) where p!=NULL.

Penultimate sentence.

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.

Do we read the penultimate sentence, and the ultimate one as ambivalent
on whether NULL is returned but that the allocation is freed in any
case? I do.
 
J

Joe Wright

pete said:
There isn't.
realloc returns either a null pointer or a pointer to memory.
I have posed a question a little upthread: Given ptr points to an area
to be freed, and then 'realloc(ptr, 0);'. Granted that realloc can
return NULL or not, will the allocation of ptr be freed? I'd like to
think so.
 
C

CBFalconer

Joe said:
CBFalconer wrote:
.... snip ...
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.

Do we read the penultimate sentence, and the ultimate one as
ambivalent on whether NULL is returned but that the allocation
is freed in any case? I do.

Which is one of the reasons I consider implementations that can
return NULL for a 0 size allocation to be brain damaged. The
allocator need only increment a 0 size request.
 
C

CBFalconer

Joe said:
.... snip ...

I have posed a question a little upthread: Given ptr points to an
area to be freed, and then 'realloc(ptr, 0);'. Granted that realloc
can return NULL or not, will the allocation of ptr be freed? I'd
like to think so.

You don't know, which is one more reason to consider such
allocaters to be brain-dead.
 
P

pete

CBFalconer said:
You don't know, which is one more reason to consider such
allocaters to be brain-dead.

N869
7.20.3.4 The realloc function
[#2] The realloc function deallocates the old object pointed
to by ptr
 
J

Joe Wright

CBFalconer said:
Joe said:
CBFalconer wrote:
... snip ...
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.
Do we read the penultimate sentence, and the ultimate one as
ambivalent on whether NULL is returned but that the allocation
is freed in any case? I do.

Which is one of the reasons I consider implementations that can
return NULL for a 0 size allocation to be brain damaged. The
allocator need only increment a 0 size request.
As free(ptr) has no case for failure, we don't (can't!) check it. If
realloc(ptr, 0) will 'free' ptr then we need not check or care the
return from realloc in this case. One might define..

void Free(void *ptr) {
realloc(ptr, 0);
}

...without caring the return value of realloc.
 
C

CBFalconer

Joe said:
CBFalconer said:
Joe said:
CBFalconer wrote:
... snip ...
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.

Do we read the penultimate sentence, and the ultimate one as
ambivalent on whether NULL is returned but that the allocation
is freed in any case? I do.

Which is one of the reasons I consider implementations that can
return NULL for a 0 size allocation to be brain damaged. The
allocator need only increment a 0 size request.
As free(ptr) has no case for failure, we don't (can't!) check it. If
realloc(ptr, 0) will 'free' ptr then we need not check or care the
return from realloc in this case. One might define..

void Free(void *ptr) {
realloc(ptr, 0);
}

..without caring the return value of realloc.

Wrong attack. The only way to get it under control is to test the
argument before calling, and proceed from there:

void *Realloc(void *p, size_t sz) {
if (!sz) sz++;
return realloc(p, sz);
}

and similarly for malloc and calloc. Now you know that a NULL
return means failure.
 
E

Eric Sosman

CBFalconer said:
Joe Wright wrote:
... snip ...

You don't know, which is one more reason to consider such
allocaters to be brain-dead.

The question isn't so much about implementations, but
about what the Standard requires/allows. In the passage
you and pete pointed out, the Standard allows realloc(p,0)
to return NULL or non-NULL at the implementation's whim.
If it returns NULL, the programmer has no way to distinguish
failure from success. (The dodge of changing zero to one is
clever, but the cure is worse than the disease: You get a
reliable success/failure indication, but at the price of
either failing unnecessarily or creating a memory leak.)

It seems to me the Standard could have defined realloc(p,0)
as equivalent to (free(p), (void*)NULL), but neither C90 nor
C99 actually chose to do so. (C90 had the free() equivalence
but didn't specify the returned value; C99 describes the
returned value but removes the free() language.)

The Rationale claims that realloc(p,0) *does* free the
memory pointed to by p, basing the claim on the deallocation
of the old object. But since the NULL return is overloaded
to mean both "failure" and "success: nothing allocated," the
programmer is stuck with a diagnostic problem.

Suggested work-around: Don't call realloc() with the second
argument equal to zero. That is, call realloc() to grow a
memory area or to shrink it, but avoid shrinking it to nothing.
If you want to free memory, use free().
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,235
Latest member
Top Crypto Podcasts_

Latest Threads

Top