Problem with malloc

C

Chris Fogelklou

Thanks for your pleasant and reasonable feedback ;-)

As I said, I always do this cast to make my code work. From firsthand
experience, I have in fact made the mistake of forgetting stdlib.h. At
least in my case, the compiler gives a "function with no prototype" warning
and the linker pukes. This is because the cast refers only to the return
value from the function, not the function itself (it must still resolve
malloc in order to cast its return value to something, right?). Even if it
did hide the compiler warning, wouldn't the build break because the linker
wouldn not be able to resolve the malloc label?

Thanks in advance!

Chris

PS: Disobeying my previous own advice to refer to the ANSI specs... :)
 
T

Thomas Stegen

Chris said:
Thanks for your pleasant and reasonable feedback ;-)




As I said, I always do this cast to make my code work.

You are sure you aren't using some sort of C++ compiler? C++ does
require the cast. If so, maybe there is some way of forcing C mode
on it...
From firsthand
experience, I have in fact made the mistake of forgetting stdlib.h. At
least in my case, the compiler gives a "function with no prototype" warning
and the linker pukes.

This is a good thing.
This is because the cast refers only to the return
value from the function, not the function itself
Right.

(it must still resolve
malloc in order to cast its return value to something, right?).

That depends on what you mean by resolve. In the C89 standard (which is
the standard that is most widely implemented) an unprototyped function
defaults to returning int and casting an int to a pointer is valid
although implementation defined. C99 "fixed" this by requiring
prototypes. C99 got that one right in my opinion.
Even if it
did hide the compiler warning, wouldn't the build break because the linker
wouldn not be able to resolve the malloc label?

That depends on the linker and compiler. Some linkers only look at
the function name at the point of call and links in a function with
the same name in the loaded libraries, others might in some way require
the function to be prototyped (however that is implemented).

It is important to note that header files are only part of the
libraries. The actual functions do not reside in them, more often
they sit about in different files and are totally oblivious to
any headers, included or not.
 
C

Chris Torek

Chris said:
... I always [have to] do this cast to make my code work [on one
particular compiler]

You are sure you aren't using some sort of C++ compiler? C++ does
require the cast. If so, maybe there is some way of forcing C mode
on it...

This is possible, but at least equally-likely is that the embedded
system compiler he mentioned is just broken (or, more accurate if
less punchy than the Anglo-Saxon-verb version, "fails to conform to
one of the ANSI/ISO C standards" :) ).

A lot of embedded-system "C compilers" have, historically, been
quite awful. The widespread use of GCC has, I think, succeeded at
"raising the bar" here: if you have a lousy embedded-system compiler
suite for target CPU "X", you need only to port the GNU Compiler
Collection to target X, and you now have a half-decent compiler
suite. (Not that porting GCC is easy, but it is a lot easier than
writing an entire compiler from scratch.)
 
R

Richard Heathfield

Chris said:
Thanks for your pleasant and reasonable feedback ;-)


As I said, I always do this cast to make my code work.

It doesn't. If the code works with the cast, it'll work without it, too.
From firsthand
experience, I have in fact made the mistake of forgetting stdlib.h.

The correct fix is to include it. Casting merely hides the problem instead
of fixing it.
At
least in my case, the compiler gives a "function with no prototype"
warning

And the correct fix is to give a prototype said:
and the linker pukes. This is because the cast refers only to the return
value from the function, not the function itself (it must still resolve
malloc in order to cast its return value to something, right?). Even if
it did hide the compiler warning, wouldn't the build break because the
linker wouldn not be able to resolve the malloc label?

No, in a typical implementation the malloc code will be tucked away in the
standard library, and the linker will find it just fine. You have
misunderstood the problem.

Here's an example of how failing to #include <stdlib.h> can cause problems.
Consider an implementation with pointer registers and integer registers,
which are kept very, very separate.

The malloc binary, which is already compiled and is tucked safely away in a
library, populates a pointer register.

Code which calls malloc but which fails to #include <stdlib.h> forces the
compiler to assume that malloc returns int. So our hypothetical
implementation generates code to call malloc and then to fetch an int from
- yes, the integer register. This is not the value malloc actually
returned! It's just whatever junk was in that register.

Since, "to get it to compile", we had to cast the call, the compiler doesn't
object when we then shove that random int into a pointer.

Result: a nasty bug, and quite hard to track down.

Of course, your compiler might not do things that way (or in some other way
that also shows up your incorrect code). With your compiler, the code might
even "work" as you expected. And you might be content with that. But one
day, if your program is actually useful, you'll want to port your code to
another platform, and another compiler.....
 
C

Chris Fogelklou

Hi Richard,
It doesn't. If the code works with the cast, it'll work without it, too.

I concede... I just checked and I don't actually have a compiler now that
craps out without the cast. I could swear that I have used one that would
fail without the cast, so I have just always casted... and never turned
back.
The correct fix is to include it. Casting merely hides the problem instead
of fixing it.

I have not disagreed with this, however, cast or no cast.
And the correct fix is to give a prototype, by including <stdlib.h>

Ditto.
 
C

CBFalconer

Joona said:
And what about stupid UNIX users? Oh, right. I forgot. To be able
to so much as boot up a UNIX machine you have to be both a
hardware and a software high wizard. How silly of me. =)
Anyway, I hope you are kidding about your attitude towards
Windows users. I don't like Microsoft any more than you do, but
that's no excuse to prejudice against their entire userbase.
^^^^^^^^^^^^^^^^^^^^

You, and Knady, should be aware that Tom is a pubescent
opinionated Ottawa teen-ager with all the diplomatic skills of Dan
Pop and very little of Dans knowledge nor Dans capability at the
English language. Toms invective level appears to be improving,
so he escapes replonking since he changed his 'from' description.

BTW, the above phrase could be either "for prejudice against" or
"to prejudge". As it stands it is highly confusing.
 
C

CBFalconer

Chris said:
.... snip ...


Um, yes you do, if you want truly portable code.


Alright... Do you want to write one up for our embedded system?
There have two compilers, one based on GCC, and neither of them
like it if you equate two pointer types to each other without
casting.

You are misusing it, especially if one is based on gcc. You NEVER
should cast a void pointer being assigned to another pointer
type. Errors from such statements usually indicate a failure to
have proper prototypes for malloc, caused by failure to #include
stdlib.h, or failure to use a C compiler, often caused by naming
source files with a .C or .cpp extension. The best statement for
the malloc call above is:

my_matrix_t *pmatrix = malloc(sizeof *pmatrix);

Casts are automatically suspect code. (double)95.34152718% of
them are unnecessary and serve only to conceal errors.
 
C

CBFalconer

Chris said:
.... snip ...

PS. Next time I write anything in this NG, I'll ensure that I have
a complete bibliography appended to the bottom and that I triple
check every fact stated with the latest ANSI standards and their
addendums.

A wise decision around here. Getting a copy of the C standard (or
N869) is also advisable. Otherwise you will soon die the death of
a thousand pecks. Remember, the vultures are circling :)
 
E

Emmanuel Delahaye

Chris Fogelklou said:
PS. Next time I write anything in this NG, I'll ensure that I have a
complete bibliography appended to the bottom and that I triple check
every fact stated with the latest ANSI standards and their addendums.

You've got it. This NG has a reputation of excellence. Trust me, you'll learn
*a lot* by reading it.
 
R

Richard Heathfield

CBFalconer said:
You, and Knady, should be aware that Tom is a pubescent
opinionated Ottawa teen-ager with all the diplomatic skills of Dan
Pop and very little of Dans knowledge nor Dans capability at the
English language.

This is, quite simply, not true.

IIRC, Tom is 21 years old.
 
K

Keith Thompson

Chris Fogelklou said:
Hi Richard,


I concede... I just checked and I don't actually have a compiler now that
craps out without the cast. I could swear that I have used one that would
fail without the cast, so I have just always casted... and never turned
back.

Turn back now. :cool:}

Perhaps you were using a C++ compiler. C++, unlike C, doesn't
implicitly convert void* to other pointer types, and C++ is close
enough to being a superset of C that you can probably compile most C
code using a C++ compiler with only a few tweaks.

But it almost always makes more sense to compile your C code with a C
compiler, and your C++ code with a C++ compiler. (Most C++ compilers
either ship with a C compiler, or can be invoked as a C compiler.)
<OT>It seldom makes sense to use malloc() in C++; use the "new"
operator instead.</OT>

In rare circumstances, it can make sense to write code that's valid C
and valid C++; such code will probably need to cast the result of
malloc(). If you don't already know why you'd need to do this, you
almost certainly shouldn't try.
 
K

Keith Thompson

Chris Fogelklou said:
Yes, I was wrong about the int. It should definitely an unsigned int. I
wrote my response very quickly and obviously didn't pull up my handy C
library help file when I did it. I just took offense to the "higher than
thou" attitude to a question that was out-and-out stated to be a homework
assignment by a beginner.

The argument to malloc is of type size_t, the same type as the result
of the sizeof operator. size_t is guaranteed to be an unsigned
integer type, but it needn't be unsigned int; in many implementations,
it's unsigned long.

That's exactly why "size_t" exists, so you don't have to know which of
the predefined unsigned integer types to use for a given implementation.

One more thing: please don't top-post. The convention here in
comp.lang.c is for your response to *follow* any quoted text from the
previous article, which should be limited to what's directly relevant
to your response (as I've done here). It may not seem like a big
deal, but it really does make it easier for your readers.

A: Because it makes your article more difficult to read.
Q: Why is top-posting bad?
 
D

Dan Pop

In said:
A lot of embedded-system "C compilers" have, historically, been
quite awful. The widespread use of GCC has, I think, succeeded at
"raising the bar" here: if you have a lousy embedded-system compiler
suite for target CPU "X", you need only to port the GNU Compiler
Collection to target X, and you now have a half-decent compiler
suite. (Not that porting GCC is easy, but it is a lot easier than
writing an entire compiler from scratch.)

I'm not sure how feasible this approach is when target X is a small
microprocessor or microcontroller. IIRC, GCC was designed with the 68000
CPU as the minimal target processor.

Furthermore, many embedded control CPUs have specific features that need
C extensions in order to be used, e.g. the bit addressing of the 8051
family or the on chip vs extern RAM or ROM.

Dan
 
T

those who know me have no need of my name

[though i've not set follow-up's this is off-topic for clc and i hope the
next round will move to e-mail, comp.arch.embedded or the gcc mailing-list]

in comp.lang.c i read:
I'm not sure how feasible this approach is when target X is a small
microprocessor or microcontroller. IIRC, GCC was designed with the 68000
CPU as the minimal target processor.

gcc currently supports arc, arm, avr, cris, ip2022, iq2000, m32r, mc68hc1[12],
embedded ppc and xtensa mcu's and embedded platforms, and even dsp's, e.g.,
ti's tms320c[34]x series.
Furthermore, many embedded control CPUs have specific features that need
C extensions in order to be used, e.g. the bit addressing of the 8051
family or the on chip vs extern RAM or ROM.

indeed, that would be part of the challenge. perhaps it would be too hard
for some platforms, but it can be a solution for some.
 

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

MALLOC problem 25
Malloc question 9
Problem with code 6
Problem with KMKfw libraries 1
Java matrix problem 3
array-size/malloc limit and strlen() failure 26
Help with if and variables 1
malloc rare error (malloc bug??) 18

Members online

No members online now.

Forum statistics

Threads
474,142
Messages
2,570,818
Members
47,362
Latest member
eitamoro

Latest Threads

Top