How to check whether malloc has allocated memory properly in case ifmalloc(0) can return valid point

  • Thread starter Shivanand Kadwadkar
  • Start date
B

BartC

pete said:
malloc(0) can return a value different from NULL.
It's a value which can and should be freed at some point.

Eventually malloc can run out of resources to keep
track of the values which it has returned
and which have not been freed.

Isn't it silly then to use up valuable resources to allocate 0 bytes?

If malloc has to return a non-NULL value for an empty allocation, why not a
pointer to the same, simple block of reserved memory? Then free() can
recognise the pointer and not do anything; and if free() isn't called, then
no extra memory is used up.

And, the application also has an extra way of telling whether an empty
allocation has been made (malloc(N) == malloc(0)).
 
K

Keith Thompson

BartC said:
Isn't it silly then to use up valuable resources to allocate 0 bytes?

Quite possibly, but it depends on what you're going to do with the
resulting pointer.
If malloc has to return a non-NULL value for an empty allocation, why not a
pointer to the same, simple block of reserved memory? Then free() can
recognise the pointer and not do anything; and if free() isn't called, then
no extra memory is used up.

Nearly the same goal could have been achieved by requiring malloc(0)
to return a null pointer. The only drawback would be that you
couldn't distinguish between a null pointer and a pointer returned
by malloc(0) -- but you can't do that anyway, since malloc(0)
can return a null pointer.
And, the application also has an extra way of telling whether an empty
allocation has been made (malloc(N) == malloc(0)).

I think the way the current definition came about is something
like this: Before C89, some implementations had malloc(0) return a
unique pointer value (that couldn't safely be dereferenced), and
some had it return a null pointer. The former is arguably more
consistent with the behavior of malloc() for non-zero sizes, and
lets you distinguish between results of different malloc(0) calls; it
makes malloc(0) a convenient way to generate a pointer value that's
non-null, guaranteed to be unique, and consumes minimal resources.
The latter avoids the conceptual problems of zero-sized objects.
The ANSI C commmittee chose to allow either behavior, probably
to avoid breaking existing implementations; they also defined the
behavior of realloc() so it could deal consistently with either a
null pointer or a pointer to a zero-sized object.

Personally, I think it would have been better to define the behavior
consistently and let implementations conform to what the standard
requires.
 
D

David Resnick

Personally, I think it would have been better to define the behavior
consistently and let implementations conform to what the standard
requires.

A reasonable solution for this is to wrap malloc. That lets you
define a behavior rather than depending on the implementations one.
e.g. if you get my_malloc(0) you could return NULL directly, or return
malloc(1). And if central handling of malloc failures is appropriate
to your program (e.g. abort on malloc() return of NULL), this wrapper
for malloc gives you a place to handle that as well.

-David
 
D

David Thompson

On 12/16/2010 11:04 AM, Ered China Luin wrote:

In the long-ago days when I used FORTRAN (II and IV), it had
no construct I'd have described as a "zero-trip loop." Specifically,
a DO loop always executed its body at least once.

Changed in (Standard) F-77. Which also added logical-IF noted
downthread. I thought F-IV had most of the F-77 enhancements, but
don't remember this one specifically. I'm sure F-II didn't.
 
I

Ian Bush

David said:
Changed in (Standard) F-77. Which also added logical-IF noted
downthread. I thought F-IV had most of the F-77 enhancements, but
don't remember this one specifically. I'm sure F-II didn't.

And as I understand it in earlier Fortran the iteration count for a "zero-trip"
loop was undefined, but many implementations performed as above,

Ian
 
G

glen herrmannsfeldt

Changed in (Standard) F-77. Which also added logical-IF noted
downthread. I thought F-IV had most of the F-77 enhancements, but
don't remember this one specifically. I'm sure F-II didn't.

The zero trip loop was not allowed in Fortran 66. Even more,
the starting, ending, and increment values all had to be greater
than zero. (It is good arrays started at one, otherwise one
wouldn't be able to loop through an array!)

Compilers would catch it at compile time if constants were used,
but not variables. It was, then, common to put the test at
the end of the loop, allowing for the 'one trip' feature.

Some even say that the BXLE instruction was added to S/360
specifically for Fortran DO loops.

Logical IF was in Fortran IV and Fortran 66. The structured
form of IF was added in Fortran 77.

Many of the Fortran IV features not in Fortran 66 were added
into Fortran 77, but also many others.

-- glen
 
R

Richard Maine

Ian Bush said:
And as I understand it in earlier Fortran the iteration count for a
"zero-trip" loop was undefined, but many implementations performed as
above,

More precisely, code that had a "zero-trip loop count" was nonconforming
to the f66 ANSI standard. It was not just that the resulting loop count
was undefined, the entire behavior of the program was undefined, as with
any other nonstandard code. This is commonly misunderstood, with the
misunderstanding even making its way into compiler switch names, which
probably then reinforced user misunderstandings. As noted, f77
standardized such code, with the zero-trip interpretation.

I've seen f77 and later compilers where a switch named -f66 did nothing
other than change zero-trip DO loops to be implemented with one trip.
That always struck me as a misleading switch name because that was *NOT*
one of the areas where the f77 standard was incompatible with f66. The
f77 standard has an annex listing the incompatibilities, and that isn't
in it, insomuch as giving an interpretation to formerly nonstandard code
does not count as an incompatibility. The -f66 compiler switch in
question did nothing about any of the actual incompatibilities between
the standards.

This probably traces back to people confusing particular compiler
implementations with the standard. That was more common in the days of
f66 than it is now. Before f66, of course, there was no formal standard
- just particular implementations, some of which were dominant enough to
amost constitute defacto standards.
 
N

nmm1

More precisely, code that had a "zero-trip loop count" was nonconforming
to the f66 ANSI standard. It was not just that the resulting loop count
was undefined, the entire behavior of the program was undefined, as with
any other nonstandard code. This is commonly misunderstood, with the
misunderstanding even making its way into compiler switch names, which
probably then reinforced user misunderstandings. As noted, f77
standardized such code, with the zero-trip interpretation.

I've seen f77 and later compilers where a switch named -f66 did nothing
other than change zero-trip DO loops to be implemented with one trip.
That always struck me as a misleading switch name because that was *NOT*
one of the areas where the f77 standard was incompatible with f66. ...

Hmm. I am afraid that I regard that as being a bit revisionist and
legalistic, because that wasn't how the Fortran 66 standard was
interpreted in the early 1970s. It's exactly like the situation
with impure functions, where the words are now given a meaning
that is different from the one they were given then.

Having said that, I don't know WHY the words were interpreted in
the way that they were then - unlike with impure functions, there
is no ambiguity, and the standard says clearly that the terminal
value must not be less than the initial value. It might be because
it says it in the section that describes how the DO statement works,
and not in the one that describes how it is used.

A possibility is that it was specified in the IBM Fortran language,
and everybody followed that in this respect. I don't think that I
have a copy of a manual of that era to check. There may be one online.



Regards,
Nick Maclaren.
 
N

nmm1

A possibility is that it was specified in the IBM Fortran language,
and everybody followed that in this respect. I don't think that I
have a copy of a manual of that era to check. There may be one online.

This annoyed me, so I did a search. Yes, it's IBM. The 7094
explicitly specified the one-trip semantics and the 360/370
language merely said that the initial value SHOULD not be larger
than the final one. See:

http://www.fh-jena.de/~kleine/history/

But I take your point that the Fortran 66 standard did unambiguously
specify that a null count DO loop was an error. What I remember
VERY distinctly was that the near-universal belief was that it
specified the one-trip semantics. It is possible that most experts
regarded the restriction as a defect in the standard, but I don't
remember that aspect.


Regards,
Nick Maclaren.
 
N

nmm1

The ones I remember would enforce this for constants. Also,
that all are greater than zero.

Yes, but that's not the point. One of the defects of the way that
almost all standards are written is that the the semantic guarantees
have to be deduced from the semantic contraints and intent. They
almost all have the concept of defined behaviour that may be rejected
by a compiler (due to resource constraints if nothing else). This
was regarded as being something else of the same category.


Regards,
Nick Maclaren.
 
G

glen herrmannsfeldt

In comp.lang.fortran (e-mail address removed) wrote:

(snip on one-trip DO)
This annoyed me, so I did a search. Yes, it's IBM. The 7094
explicitly specified the one-trip semantics and the 360/370
language merely said that the initial value SHOULD not be larger
than the final one.

The ones I remember would enforce this for constants. Also,
that all are greater than zero.
 
R

Richard Maine

But I take your point that the Fortran 66 standard did unambiguously
specify that a null count DO loop was an error. What I remember
VERY distinctly was that the near-universal belief was that it
specified the one-trip semantics.

Yes, I recall that near-universal belief as well. I ascribe it to
confusion between the standard and particular implementations. After
all, what I most recall as near universal in f66 days was that most
programmers never even saw a copy of the actual standard, but relied on
vendor documentation or 3rd-party books. I personally never saw a copy
of the f66 standard until well after f77 was out. I'm not sure I ever
even met anyone during the f66 timeframe who had seen the standard.

Another thing I recall from that timeframe was working with some
compilers that did not have one-trip semantics. Memory has gotten vague
enough that I can't say for sure which ones they were, but I sure recall
working with some because I recall having to fix code that assumed the
behavior.
 
U

Uno

This probably traces back to people confusing particular compiler
implementations with the standard. That was more common in the days of
f66 than it is now. Before f66, of course, there was no formal standard
- just particular implementations, some of which were dominant enough to
[almost] constitute defacto standards.

Since this is x-posted to both C and Fortran groups, I think we need the
syntax name to describe which standard. It was my understanding that
before 1966, IBM was "standard fortran." Were there other vendors that
could make the same claim? (I was busy being born in '66.)

I would say that C became "standard" in '89-'90 with ANSI. Would people
say that K&R1 was a de facto (C) standard?

I'm reading _Perl Cookbook_ today and find a quote from clc contributor
Chris Torek at the beginning of §9: "Unix has its weak points, but its
file system is not of them."

(Hey Chris, if you happen to read this and are still in Salt Lake,
what's the weather and roads like? I'm coming to Zion for New Years.
I'm nervous about driving conditions with my truck this time. Last year
I drove a subaru outback and was all over the roads.)

Cheers,
 
S

Sjouke Burry

Hmm. I am afraid that I regard that as being a bit revisionist and
legalistic, because that wasn't how the Fortran 66 standard was
interpreted in the early 1970s. It's exactly like the situation
with impure functions, where the words are now given a meaning
that is different from the one they were given then.

Having said that, I don't know WHY the words were interpreted in
the way that they were then - unlike with impure functions, there
is no ambiguity, and the standard says clearly that the terminal
value must not be less than the initial value. It might be because
it says it in the section that describes how the DO statement works,
and not in the one that describes how it is used.

A possibility is that it was specified in the IBM Fortran language,
and everybody followed that in this respect. I don't think that I
have a copy of a manual of that era to check. There may be one online.



Regards,
Nick Maclaren.
From the f77 manual of MS fortran 5.1:

Metacommand:$DO66
The following F66 semantics are used:
*Statements within a Do loop are always executed at least once.
*Extended range is permitted;control may transfer into the syntactic
body of a DO statement.
The range of the DO statement is thereby extended to include, logically,
any statement that may be executed between a DO statement and
its terminal statement.
However, the transfer of control into the range of a DO statement
prior the the execution of the DO statement or following the final
execution of its terminal statement is invalid.

Whatever all that means, verbatim from the MS Fortran reference,
typing errors are free of charge :) .
 
R

Richard Maine

Uno said:
It was my understanding that before 1966, IBM was "standard fortran."

No. It was just IBM's Fortran, generally with the particular compiler
version number. The term "standard" was neither applicable nor generally
used.
 
M

Malcolm McLean

A reasonable solution for this is to wrap malloc.  That lets you
define a behavior rather than depending on the implementations one.
e.g. if you get my_malloc(0) you could return NULL directly, or return
malloc(1).  And if central handling of malloc failures is appropriate
to your program (e.g. abort on malloc() return of NULL), this wrapper
for malloc gives you a place to handle that as well.
You can easily write mymalloc.c. The problem is that your leaf
routines become dependent on it, and therefore no longer leaf
routines. So you can't move them to another program, and they can't be
corrected by someone who isn't an expert in your particular program.
 
U

Uno

No. It was just IBM's Fortran, generally with the particular compiler
version number. The term "standard" was neither applicable nor generally
used.

I can hardly conceive of what happened during that conception, but I
wouldn't consider any stroke of it contrary to the open source movement.

(I'm sure DoD and the Usual Suspects played their part.)
 
N

nmm1

Yes, I recall that near-universal belief as well. I ascribe it to
confusion between the standard and particular implementations. After
all, what I most recall as near universal in f66 days was that most
programmers never even saw a copy of the actual standard, but relied on
vendor documentation or 3rd-party books. I personally never saw a copy
of the f66 standard until well after f77 was out. I'm not sure I ever
even met anyone during the f66 timeframe who had seen the standard.

I had, but I rarely used it.

As far as I know, it was one of the first standards to use the modern
informal conventions, which are the source of most of these problems.
Most previous languages had no standard-like specification or were in
a semi-mathematical notation.
Another thing I recall from that timeframe was working with some
compilers that did not have one-trip semantics. Memory has gotten vague
enough that I can't say for sure which ones they were, but I sure recall
working with some because I recall having to fix code that assumed the
behavior.

I can't remember if I used them or only wrote code that would be
expected to work on them.


Regards,
Nick Maclaren.
 
N

nmm1

I can hardly conceive of what happened during that conception, but I
wouldn't consider any stroke of it contrary to the open source movement.

If I have parsed your sentence correctly, I find it incomprehensible.
(I'm sure DoD and the Usual Suspects played their part.)

Nah. They did with the USMIL extensions, which had some later
effect, but had effectively no effect on Fortran before (really)
Fortran 90 and possibly a couple of things in Fortran 77.


Regards,
Nick Maclaren.
 
R

Richard Maine

If I have parsed your sentence correctly, I find it incomprehensible.

My sentiments as well. I honestly can't tell whether it is intended to
say something, or whether it is just some kind of nonsensical playing
with words intended to be humorous. In one case, the meaning escapes me.
In the other case, the humor does. I often have this problem with Uno's
posts. I can't tell his serious comments from his joking around. I
probably should resist the temptation to respond to them at all.
 

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

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top