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

malloc and pointer casting

P: n/a
Hello, I'm new to this list and to Usenet in general,
so please forgive (and advice) me, if I do something wrong.

Anyway.

I am a bit confused, because I always thought one
_should_ explicitly cast the void* pointer returned by malloc.
Now I read postings saying that this is dangerous.

Could somebody please clearify this?

Thanks
Mirko

Nov 15 '05 #1
Share this Question
Share on Google+
14 Replies


P: n/a
Mirko wrote on 31/08/05 :
Hello, I'm new to this list and to Usenet in general,
so please forgive (and advice) me, if I do something wrong.

I am a bit confused, because I always thought one
_should_ explicitly cast the void* pointer returned by malloc.


You can, but it's just another waste of time. Please read the FAQ.

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

I once asked an expert COBOL programmer, how to
declare local variables in COBOL, the reply was:
"what is a local variable?"
Nov 15 '05 #2

P: n/a

"Mirko" <mk****@gmx.net> wrote in message
news:11**********************@f14g2000cwb.googlegr oups.com...
Hello, I'm new to this list and to Usenet in general,
so please forgive (and advice) me, if I do something wrong.

Anyway.

I am a bit confused, because I always thought one
_should_ explicitly cast the void* pointer returned by malloc.
Why did you think that? If you learned it from a book,
please tell us the title and author so we can warn
others about it.
Now I read postings saying that this is dangerous.

Could somebody please clearify this?


Casting the return value from 'malloc()' can mask errors
(e.g. failure to provide its prototype via #including
<stdlib.h>). In C89, calling a function without a
prototype will cause a compiler to assume its return
type is 'int'. So the returned pointer would be
treated as type 'int', often corrupting its value.
C99 makes this issue moot since it requires a prototype
be in scope for any function called. However C99 is
not in very widespread use yet, so this is still a
very real issue.

A 'void*' pointer can be implicitly converted to any
other pointer type without any cast.

IOW do things like so:

#include <stdlib.h>

int main()
{
int *p = malloc(sizeof *p * 100); /* 100 is arbitrary
number for this example */

if(p)
{
/* do something with 'p' */

free(p);
}
else
/* memory allocation failed, take corrective action */

return 0;
}

Note that I also addressed another common mishandling of 'malloc()':
failure to check its return value to see if it succeeded or not.
comp.lang.c Frequently Asked Questions:
http://www.eskimo.com/~scs/C-faq/faq.html

-Mike
Nov 15 '05 #3

P: n/a
Mike Wahler wrote:

"Mirko" <mk****@gmx.net> wrote in message

[... casting the return from malloc() ...]
Now I read postings saying that this is dangerous.

Could somebody please clearify this?


Casting the return value from 'malloc()' can mask errors
(e.g. failure to provide its prototype via #including
<stdlib.h>). In C89, calling a function without a
prototype will cause a compiler to assume its return
type is 'int'. So the returned pointer would be
treated as type 'int', often corrupting its value.

[...]

To clarify this point...

On some systems, sizeof(int) < sizeof(void*), meaning that, at best,
the upper bits of the return value are lost, resulting in an invalid
pointer. (For example, a 16-bit DOS system with 32-bit FAR pointers.)

Worse, some systems return pointers differently than integers. For
example, I've seen a CPU with two sets of registers -- one for data,
one for addresses -- and the return value from functions was stored
in the appropriate register. So, malloc() returns the pointer in the
A0 register, while your code, thinking that malloc() returns an int,
reads the D0 register for the value.

Casting the return from malloc() would hide any warnings.
--
+-------------------------+--------------------+-----------------------------+
| Kenneth J. Brody | www.hvcomputer.com | |
| kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------------+
Don't e-mail me at: <mailto:Th*************@gmail.com>
Nov 15 '05 #4

P: n/a
Mike Wahler wrote:
I am a bit confused, because I always thought one
_should_ explicitly cast the void* pointer returned by malloc.


Why did you think that? If you learned it from a book,
please tell us the title and author so we can warn
others about it.


Brian W. Kernighan, Dennis M. Ritchie: The C Programming Language (2nd
Edition).
Christian
Nov 15 '05 #5

P: n/a
Christian Kandeler said:
Mike Wahler wrote:
I am a bit confused, because I always thought one
_should_ explicitly cast the void* pointer returned by malloc.


Why did you think that? If you learned it from a book,
please tell us the title and author so we can warn
others about it.


Brian W. Kernighan, Dennis M. Ritchie: The C Programming Language (2nd
Edition).


Fortunately for the faith of the faithful, K&R have dealt with this in their
errata:

http://cm.bell-labs.com/cm/cs/cbook/2ediffs.html

--
Richard Heathfield
"Usenet is a strange place" - dmr 29 July 1999
http://www.cpax.org.uk
Email rjh at the above domain

Nov 15 '05 #6

P: n/a

Mirko wrote:
Hello, I'm new to this list and to Usenet in general,
so please forgive (and advice) me, if I do something wrong.

Anyway.

I am a bit confused, because I always thought one
_should_ explicitly cast the void* pointer returned by malloc.
Now I read postings saying that this is dangerous.

Could somebody please clearify this?

Thanks
Mirko


You've already gotten the correct answer, I just want to add a little
historical context.

Prior to C89, malloc() returned a char* instead of a void*, so a cast
*was* required if the target wasn't a char*. So anyone who's been
using C since before C89 is likely to still use the cast out of habit,
even though it's no longer necessary.

Also, anyone who goes back and forth between C++ and C is likely to use
the cast, since C++ *doesn't* allow implicit conversions between void*
and any other pointer type (but if you're writing C++, you shouldn't be
using malloc() anyway).

Nov 15 '05 #7

P: n/a

Thanks to all who have answered, got exactly the information I was
after.

Perhaps one should add some lines to the FAQ, since it is not very
informativ (presice) on that topic.

Sorry, for this, to take so long, but I don't have an own internet
access,
so I can't read news regulary (in fact, it can take one or two weeks
for
me to respond).

Thanks again

Greetings
Mikro

Nov 15 '05 #8

P: n/a
Mike Wahler wrote:
Mirko wrote:
I am a bit confused, because I always thought one
_should_ explicitly cast the void* pointer returned by malloc.
Why did you think that? If you learned it from a book,
please tell us the title and author so we can warn
others about it. Uhm, just too many... (mainly german, so called From-Beginner-to-Expert
books).

C99 makes this issue moot since it requires a prototype
be in scope for any function called.

Perhaps I'm mixing up different meanings of "scope", but if I
understand
you correctly, then it is forbidden in C99 to do something like this
(IMHO bad style anyway):

foo.c
/* C99 would _require_ this; prior, we just get a warning. */
/* int foo(void); */

int main(void)
{
/* Wired, but C99 wouldn't complain, since prototype would be in
scope. */
/* int foo(void); */

return foo(); /* error: no prototype in scope */
}

int foo(void)
{
return 0;
}

Nov 15 '05 #9

P: n/a
Mirko wrote:
I am a bit confused because I always thought [that]
one _should_ explicitly cast the void* pointer returned by malloc.
That's correct.
Now I read postings saying that this is dangerous.
FUD

http://wombat.doc.ic.ac.uk/foldoc/
Could somebody please clarify this?
C++ requires the explicit cast but C does not.
Try to write code that will compile as either C or C++.
cat main.c #include <stdlib.h>

int main(int argc, char* argv[]) {
const
size_t n = 100; // arbitrary size for this example
int* p = (int*)malloc(n*sizeof(int));

if (NULL == p) { // Memory allocation failed.
// Take corrective action.
}
else {
// Do something with 'p'.
}

free(p);
return 0;
}
gcc -x c -Wall -std=c99 -pedantic -o main main.c
gcc -x c++ -Wall -ansi -pedantic -o main main.c


Don't write C code that C++ cannot accept.
C++ will eventually replace C
and you will either need to re-write your code or throw it away.
Nov 15 '05 #10

P: n/a

E. Robert Tisdale wrote:
Mirko wrote:
I am a bit confused because I always thought [that]
one _should_ explicitly cast the void* pointer returned by malloc.


That's correct.


In C++, yes. In K&R C, yes. In C89 and later, *no*.

Put another way, it's just as correct as casting the result of "new".

Snipping the rest.

Nov 15 '05 #11

P: n/a
John Bode wrote:
E. Robert Tisdale wrote:
Mirko wrote:

I am a bit confused because I always thought [that]
one _should_ explicitly cast the void* pointer returned by malloc.


That's correct.


In C++, yes. In K&R C, yes. In C89 and later, *no*.


BZZT! In K&R C there is no such thing as a void*, so it cannot be true
that in K&R C one should explicitly cast the void* pointer returned by
malloc. Casting the char* returned by a K&R C library's malloc would be
a good idea, though.
Nov 15 '05 #12

P: n/a

Martin Ambuhl wrote:
John Bode wrote:
E. Robert Tisdale wrote:
Mirko wrote:
I am a bit confused because I always thought [that]
one _should_ explicitly cast the void* pointer returned by malloc.

That's correct.


In C++, yes. In K&R C, yes. In C89 and later, *no*.


BZZT! In K&R C there is no such thing as a void*, so it cannot be true
that in K&R C one should explicitly cast the void* pointer returned by
malloc. Casting the char* returned by a K&R C library's malloc would be
a good idea, though.


Brain fart -- I misread "the void* pointer returned by malloc" as "the
value returned by malloc".

It's been a long week already, and this just made it longer.

Nov 15 '05 #13

P: n/a
"E. Robert Tisdale" <E.**************@jpl.nasa.gov> writes:
Mirko wrote:
I am a bit confused because I always thought [that]
one _should_ explicitly cast the void* pointer returned by malloc.
That's correct.


No, it isn't.
Now I read postings saying that this is dangerous.


FUD

http://wombat.doc.ic.ac.uk/foldoc/
Could somebody please clarify this?


C++ requires the explicit cast but C does not.
Try to write code that will compile as either C or C++.


Write in C, or write in C++. A very few developers have a legitimate
need to write code that's compatible with both. If you have such a
need, chances are you're P.J. Plauger, and you don't need advice from
me.
Don't write C code that C++ cannot accept.
C++ will eventually replace C
and you will either need to re-write your code or throw it away.


There is no reason to believe that C++ will replace C.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 15 '05 #14

P: n/a
On 8 Sep 2005 06:26:39 -0700, "Mirko" <mk****@gmx.net> wrote:
Mike Wahler wrote: <snip>
C99 makes this issue moot since it requires a prototype
be in scope for any function called.


Actually C99 requires a declaration but not necessarily a prototype. A
prototype in C is a specific kind of declaration or definition, that
specifies the types (at least) of the parameters in the parentheses
indicating that it is a function, although many people misuse the term
to mean any declaration of a function, especially "published".
Perhaps I'm mixing up different meanings of "scope", but if I
understand
you correctly, then it is forbidden in C99 to do something like this
(IMHO bad style anyway):

foo.c
/* C99 would _require_ this; prior, we just get a warning. */
/* int foo(void); */

int main(void)
{
/* Wired, but C99 wouldn't complain, since prototype would be in
scope. */
/* int foo(void); */

return foo(); /* error: no prototype in scope */
}

<snip>

Sort of. Let's review:

int foo (void); is a prototype declaration of a function with no
arguments. int foo (); is a declaration but not a prototype.
Prototypes are better because they allow more error checking by the
compiler and appropriate automatic conversion of arguments (for
functions that take arguments, of course) but they are not required,
not even in C99. (They are, effectively, in C++.)

Before C99, you can declare a function at file scope a.k.a. top level
and it applies to the whole rest of the file (translation unit) unless
shadowed, or you can declare it within a function body or other block
and it applies only within that block. Or, if you call a named
function directly and it you haven't declared it either place, the
compiler assumes an implicit declaration like int foo() i.e. returning
int and accepting unspecified fixed default-promoted arguments.

It is considered poor style to put function declarations locally in a
function/block, because that's not where people expect to see them or
find them when looking, and it allows the coder to accidentally or
intentionally have inconsistent declarations e.g. char * foo (int) in
one place and void foo (int, char *) in another, which is wrong and
often badly wrong, without the compiler detecting. But it is legal.

C99 removes the last option, implicit declaration. You can declare,
prototype or not, at file scope or local scope. But you must declare.

- David.Thompson1 at worldnet.att.net
Nov 15 '05 #15

This discussion thread is closed

Replies have been disabled for this discussion.