473,395 Members | 1,977 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

Confused with malloc

I'm sorry for asking such a silly question, but I can't quite get my head
around malloc. Using gcc I have always programmed in a lax C/C++ hybrid
(which I suppose is actually c++). But I have started messing around in Plan
9, and that sort of thing is totally no go there :).

Is this correct to allocate memory for my struct? It works on my computer,
but I'm suspicious that I'm doing it wrong.

--

struct NODE;

struct NODE {
char string[80];
struct NODE *next;
}

int main()
{
struct NODE *first;

first = (struct NODE) malloc(sizeof(struct NODE));

first->next = (struct NODE) malloc(sizeof(struct NODE));

free(first);

return 0;
}

Is it necessary to malloc the struct 'first'?
Nov 14 '05 #1
34 6380
Sorry, I see one error in that code already, there should be a semicolon at
the end of the struct :).
Nov 14 '05 #2
Richard Hunt wrote:
I'm sorry for asking such a silly question, but I can't quite get my head
around malloc. Using gcc I have always programmed in a lax C/C++ hybrid
(which I suppose is actually c++). But I have started messing around in Plan
9, and that sort of thing is totally no go there :).

Is this correct to allocate memory for my struct? It works on my computer,
but I'm suspicious that I'm doing it wrong.
No, it's not correct. It shouldn't even compile. Here are the
diagnostics I got:

"C:\cygwin\bin\gcc.exe" -W -Wall -Wcast-align -Wwrite-strings
-Wno-sign-compare -Wno-unused-parameter -Wpointer-arith -ansi
-pedantic-errors -ggdb -c fun.c
fun.c:9: error: two or more data types in declaration of `main'
fun.c: In function `main':
fun.c:12: warning: implicit declaration of function `malloc'
fun.c:12: error: conversion to non-scalar type requested
fun.c:14: error: conversion to non-scalar type requested
fun.c:16: warning: implicit declaration of function `free'
Terminated with exit code 1

struct NODE;
This forward declaration is not useful.

struct NODE {
char string[80];
struct NODE *next;
}
fun.c:9: error: two or more data types in declaration of `main'

You missed a semicolon here.

int main()
Prefer 'int main(void)'. "()" and "(void)" mean completely different
things in C.
{
struct NODE *first;

first = (struct NODE) malloc(sizeof(struct NODE));
fun.c:12: warning: implicit declaration of function `malloc'

malloc has not been declared, so using it causes it to be implicitly
declared to return 'int'. This is wrong, and causes the behavior to be
undefined.
fun.c:12: error: conversion to non-scalar type requested

You've also cast to the wrong type.

You should probably not cast the return from malloc. It doesn't do
anything useful, makes maintenance more difficult, and can hide errors.
If you had cast to the correct type, and the compiler had not bothered
to warn about the implicit declaration of malloc (it's not required to,
and some don't), then you'd have a silent case of undefined behavior.

Finally, consider using the comp.lang.c-approved malloc idiom:

p = malloc(N * sizeof(*p));

This is less error-prone and more self-maintaining than other idioms.

first->next = (struct NODE) malloc(sizeof(struct NODE));
All the same problems as before, plus undefined behavior (probably
causing a crash) if the first malloc fails.

free(first);
Memory leak. You never freed first->next, and now you have no way to do so.

return 0;
}

Is it necessary to malloc the struct 'first'?


I'm not sure I know what you mean. 'first' is a pointer, not a struct.
It has to be made to point to something if you want it to be useful. A
malloced object is one possible choice.

In the context of this example, you didn't need malloc at all. You could
have done this:

struct NODE first, next;
first.next = next;

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.
Nov 14 '05 #3
On Sun, 28 Dec 2003 18:28:52 -0000, "Richard Hunt" <01****@fg.dfg>
wrote:
I'm sorry for asking such a silly question, but I can't quite get my head
around malloc. Using gcc I have always programmed in a lax C/C++ hybrid
(which I suppose is actually c++). But I have started messing around in Plan
9, and that sort of thing is totally no go there :).

Is this correct to allocate memory for my struct? It works on my computer,
but I'm suspicious that I'm doing it wrong.

--
You shouldn't use this separator. Many news readers treat everything
below as signature material.

struct NODE;

struct NODE {
char string[80];
struct NODE *next;
}
;

int main()
{
struct NODE *first;

first = (struct NODE) malloc(sizeof(struct NODE));
This is a constraint violation. You probably meant the cast to be
(struct NODE*).

In C you should never cast the return from malloc. You should also
#include stdlib.h to insure a prototype is in scope. The preferred C
construct is

first = malloc(sizeof *first)

first->next = (struct NODE) malloc(sizeof(struct NODE));
You ought to compile your code before submitting it.

free(first);
You do realize that this creates a memory leak?

return 0;
}

Is it necessary to malloc the struct 'first'?


If you don't, will first->next even exist?
<<Remove the del for email>>
Nov 14 '05 #4

"Richard Hunt" <01****@fg.dfg> wrote in message
I'm sorry for asking such a silly question, but I can't quite get my head
around malloc. Using gcc I have always programmed in a lax C/C++
hybrid (which I suppose is actually c++).
It's C-like C++. Unless you really know what you doing this has the
disadvantages of C and C++, and the advantages of neither.
struct NODE;
Get rid of this.
struct NODE {
char string[80];
struct NODE *next;
}
OK.
int main()
{
struct NODE *first;

first = (struct NODE) malloc(sizeof(struct NODE));
You mean first = (struct NODE *) malloc( sizeof(struct NODE));
or you can just say first = malloc( sizeof(struct NODE));

this means that first now points to an area of memory big enough to contain
one struct NODE. ie 80 bytes plus a few for the pointer.

Now you should check that malloc() has succeeded.
if(first == NULL)
{
fprintf(stderr, "Out of memory\n");
exit(EXIT_FAILURE);
}
first->next = (struct NODE) malloc(sizeof(struct NODE));
Imagine we want to create a linked list of N nodes.

(temp is a struct NODE *)
temp = first;
for(i=0;i<N-1;i++)
{
temp->next = malloc(sizeof(NODE));
if(!temp->next)
{
fprintf(stderr, "Out of memory\n");
exit(EXIT_FAILURE);
}
strcpy(temp->next->string, "Empty string");
temp ->next->next = 0;
temp = temp->next;
}
free(first);
You must free memory you allocate, in this case both first and first->next.
If you free first then you will orphan first->next.
Generally, when freeing a linked list, free the last member first and then
work upwards.
return 0;
}

Is it necessary to malloc the struct 'first'?

You can create a structure on the stack.

struct NODE first.

If you know how many structures you need in the linked list, you can create
an array

struct NODE list[100].
and then set the nest pointers.

However if the list can contain an arbitrary number of members, then you
need to allocate dynamically.
Nov 14 '05 #5
Sorry everyone, I wrote this example out quickly from memory without any
thought, before I went out. Your advice was useful though, thanks for trying
:).
Nov 14 '05 #6
Here's a modified version of the program. I realize that it isn't a sensible
program, sorry. Does this look better?

#include <stdlib.h>

struct NODE;

/*
* This was why I had the forward declaration in the original, sorry
*/

struct interior {
char text[100];
struct NODE *next;
};

struct NODE {
char text[100];
struct interior yes;
struct interior no;
};

int main(int argc, char **argv)
{
struct NODE *first;

first=malloc(sizeof(struct NODE));

first->yes.next=malloc(sizeof(struct NODE));
first->no.next=malloc(sizeof(struct NODE));

/*
* free part skipped, see question
*/

return 0;
}

Assuming that I continue creating further nodes in this tree, what would be
the correct way to free them all? I can't work backwards, because there are
no pointers to earlier in the tree. The example I used for this said that I
could just do free(first). (It also claimed to be a C example, but used the
new keyword.)

I learnt what C I know originally from Illustrating ansi C, because it was
about, and I couldn't afford to get any more books. It isn't very
comprehensive, but I think it's accurate. Shame I lost it.
Nov 14 '05 #7
Richard Hunt wrote:
Here's a modified version of the program. I realize that it isn't a sensible
program, sorry. Does this look better?

#include <stdlib.h>

struct NODE;

/*
* This was why I had the forward declaration in the original, sorry
*/

struct interior {
char text[100];
struct NODE *next;
};

struct NODE {
char text[100];
struct interior yes;
struct interior no;
};

int main(int argc, char **argv)
{
struct NODE *first;

first=malloc(sizeof(struct NODE));
I would still recommend applying 'sizeof' to the object, not the type.
Otherwise you are sacrificing a large part of the benefit of the
clc-approved malloc idiom and making it more error-prone.

first = malloc(sizeof(*first));

OR

first = malloc(sizeof *first);

If you really want to give the type here (for some reason), I wouldn't
use the clc idiom at all. I'd probably do something completely
different, like the following:

#define ALLOC(type) (type *)malloc(sizeof(type))
/* ... */
first = ALLOC(struct NODE);

This will cause a diagnostic if you allocate space for the wrong type,
but still may suppress a useful diagnostic if you forget to #include
<stdlib.h>.

first->yes.next=malloc(sizeof(struct NODE));
first->no.next=malloc(sizeof(struct NODE));

/*
* free part skipped, see question
*/

return 0;
}

Assuming that I continue creating further nodes in this tree, what would be
the correct way to free them all? I can't work backwards, because there are
no pointers to earlier in the tree. The example I used for this said that I
could just do free(first). (It also claimed to be a C example, but used the
new keyword.)


Then the example was crap. You *must* free() everything you malloc() (or
realloc(), or calloc()). That means each malloc() invocation needs a
corresponding free() invocation (applied to a pointer with the same
value as the pointer returned from malloc()).

[OT: Also, even in C++ where the 'new' keyword exists, you cannot free()
memory allocated with 'new' - you have to use 'delete' with 'new' and
free() with malloc(). And even in C++, you have to match every
invocation of an allocation function (or operator) with an invocation of
the corresponding deallocation function (or operator). Neither C nor C++
require any sort of automatic clean-up of dynamically allocated memory
at any time, even at program termination.]

The way memory is usually freed for a tree is to do a regular old
post-order traversal, freeing as you go. Something like this:

void free_tree(NODE *ptr)
{
if (ptr)
{
free_tree(ptr->left_child);
free_tree(ptr->right_child);
free(ptr);
}
}

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.
Nov 14 '05 #8
> I would still recommend applying 'sizeof' to the object, not the type.
Otherwise you are sacrificing a large part of the benefit of the
clc-approved malloc idiom and making it more error-prone.

first = malloc(sizeof(*first));

OR

first = malloc(sizeof *first);
Sorry, I hadn't taken in what you said before, I was too busy trying to come
up with a correct example
[OT: Also, even in C++ where the 'new' keyword exists, you cannot free()
memory allocated with 'new' - you have to use 'delete' with 'new' and
free() with malloc(). And even in C++, you have to match every
invocation of an allocation function (or operator) with an invocation of
the corresponding deallocation function (or operator). Neither C nor C++
require any sort of automatic clean-up of dynamically allocated memory
at any time, even at program termination.]
Ah, free() instead of delete was probably my memory failing me. But my basic
point was definitely what the example said.
The way memory is usually freed for a tree is to do a regular old
post-order traversal, freeing as you go. Something like this:

void free_tree(NODE *ptr)
{
if (ptr)
{
free_tree(ptr->left_child);
free_tree(ptr->right_child);
free(ptr);
}
}


Thanks, thats what I wanted. I think I should invest in some decent books,
it's alright me soldiering on slowly in private, but I don't want to waste
any more of other peoples time.
Nov 14 '05 #9
Richard Hunt wrote:
.... snip ...
Assuming that I continue creating further nodes in this tree,
what would be the correct way to free them all? I can't work
backwards, because there are no pointers to earlier in the tree.
The example I used for this said that I could just do free(first).
(It also claimed to be a C example, but used the new keyword.)


Study this elementary example:

#include <stdlib.h>

#define ITEMS 10

struct node {
struct node *next;
int datum;
};

int main(void)
{
struct node *root, *temp;;
int i; /* just a counter */

root = NULL;
for (i = 0; i < ITEMS; i++) {
temp = malloc(sizeof *temp);
if (temp) /* i.e temp != NULL */ {
temp->next = root; /* save previous */
root = temp; /* revise root value */
}
else {
/* malloc failed, bail out, temp == NULL */
return EXIT_FAILURE;
}
}
/* now we have allocated 10 nodes, the last of which
is pointed to by root, and each nodes next pointer
points to an earlier node, or is NULL at the end */

/* free them all */
while {root) /* i.e. while (root != NULL) */
temp = root->next; /* won't be available after free */
free(root);
root = temp; /* and see if at the end */
}
return 0;
} /* main untested */

Note that datum has never been used. Most of the comments are not
normally necessary, but I added them to clarify what things were
about to you.

After that is perfectly clear, see if you can create a binary
tree. Then consider ways to walk it, known as preorder, inorder,
and postorder. The sort of node you will want will be something
like:

struct node {
struct node *left, *right;
int datum;
};

Draw pictures with boxes representing nodes and lines representing
pointers. Don't forget that NULL points nowhere.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 14 '05 #10
Kevin Goodsell <us*********************@neverbox.com> wrote:
Richard Hunt wrote:
int main()


Prefer 'int main(void)'. "()" and "(void)" mean completely different
things in C.


No, they don't. This is a function _definition_, and in a function
definition sometype function() and sometype function(void) mean exactly
the same thing: function() is a function taking no arguments and
returning a value of type sometype.
What you say _is_ true for function declarations:

sometype function(void);

means: I have, somewhere, defined a function called function(), taking
no arguments, and returning a sometype; but

sometype function();

means: I have, somewhere, defined a function called function(),
returning a sometype, and I'm not telling you what kind of arguments it
takes.
But this is only true for declarations, not for definitions.

Richard
Nov 14 '05 #11
Barry Schwarz <sc******@deloz.net> wrote:
On Sun, 28 Dec 2003 18:28:52 -0000, "Richard Hunt" <01****@fg.dfg>
wrote:
--


You shouldn't use this separator. Many news readers treat everything
below as signature material.


Then many newsreaders are broken[1]. A sigsep is
dash-dash-SPACE-newline.

Richard

[1] I know, I know... get a real newsreader, anyway!
Nov 14 '05 #12
Richard Bos wrote:
Kevin Goodsell <us*********************@neverbox.com> wrote:

Richard Hunt wrote:
int main()


Prefer 'int main(void)'. "()" and "(void)" mean completely different
things in C.

No, they don't. This is a function _definition_, and in a function
definition sometype function() and sometype function(void) mean exactly
the same thing: function() is a function taking no arguments and
returning a value of type sometype.
What you say _is_ true for function declarations:

sometype function(void);

means: I have, somewhere, defined a function called function(), taking
no arguments, and returning a sometype; but

sometype function();

means: I have, somewhere, defined a function called function(),
returning a sometype, and I'm not telling you what kind of arguments it
takes.
But this is only true for declarations, not for definitions.


While discussing this exact issue, somebody pointed out to me a while
back that

int main()
{
/*...*/
}

is both a definition *and* a declaration. Maybe I'm wrong (it's much too
late for me to go looking through the standard for a precise answer),
but my guess would be that, in the absence of a declaration that
provides more information (i.e., a prototype), the rules of a
declaration apply to the definition. Consider this:

int func()
{
return 1;
}

int main(void)
{
func(1);
return 0;
}

gcc (-W -Wall -ansi -pedantic) accepts it with no complaints. Comeau
accepts it with only a warning. The same happens with this code:

int main()
{
main(1.2, 23, "huh?");
return 0;
}

I don't know exactly what the deal is, but if 'main()' is supposed to be
equivalent to 'main(void)' then both of these compilers are broken in
this respect.

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.
Nov 14 '05 #13
begin followup to Richard Bos:
[...] in a function definition sometype function() and
sometype function(void) mean exactly the same thing:
$ cat a.c
#include <stdio.h>
int foo() { return puts("foo"); }
int main() { return foo(123);

$ gcc -Wall -ansi -pedantic a.c && ./a.out
foo

Repeat the thing with "foo(void)" und the compiler will complain:

a.c: In function `main':
a.c:3: too many arguments to function `foo'
[...] But this is only true for declarations, not for definitions.


You are proposing a magic difference in the meaning of signatures
between prototype and function body. Well, at least one compiler
knows nothing of that. And then I will offer you an alternative
explanation requiring no magic at all.

You can define functions with as many or few arguments as you like.
The caller of the function is free to pass as many or as few
arguments as he likes. This will work for two reasons:

1. The linker knows only the function name, nothing else.
2. Under the C calling convention the caller of the function is
responsible for any required disposal of function arguments
previously pushed on the stack.

So for all practical purposes a function is not required to know
how many arguments it got, be it "int" or "int, char**" or even
"int, char**, char**".

--
Für Google, Tux und GPL!
Nov 14 '05 #14
"Richard Bos" <rl*@hoekstra-uitgeverij.nl> wrote in message
news:3f****************@news.individual.net...
Kevin Goodsell <us*********************@neverbox.com> wrote:
Richard Hunt wrote:
int main()


Prefer 'int main(void)'. "()" and "(void)" mean completely different
things in C.


No, they don't. This is a function _definition_, and in a function
definition sometype function() and sometype function(void) mean exactly
the same thing: function() is a function taking no arguments and
returning a value of type sometype.


Nonetheless, () is not a prototype, so a subtle difference is that the
following does not require a diagnostic...

int main()
{
main(0, (char **) 0);
}

That said, (void) is also preferable for the simple reason that () style
parameter lists are (still!) deprecated.

--
Peter
Nov 14 '05 #15
"Alexander Bartolich" <al*****************@gmx.at> wrote in message
news:bs************@ID-193444.news.uni-berlin.de...
begin followup to Richard Bos:
[...] in a function definition sometype function() and
sometype function(void) mean exactly the same thing:
$ cat a.c
#include <stdio.h>
int foo() { return puts("foo"); }
int main() { return foo(123);

$ gcc -Wall -ansi -pedantic a.c && ./a.out
foo


I must have an old gcc port...

% type a.c
#include <stdio.h>
int foo() { return puts("foo"); }
int main() { return foo(123);

% gcc -Wall -ansi -pedantic a.c
a.c: In function `main':
a.c:4: parse error at end of input

%

Hope it wasn't your news client, that would be ironic.
Repeat the thing with "foo(void)" und the compiler will complain:

a.c: In function `main':
a.c:3: too many arguments to function `foo'


Missing } aside, in that circumstance, a diagnostic is required as it is a
constraint violation.
[...] But this is only true for declarations, not for definitions.


You are proposing a magic difference in the meaning of signatures
between prototype and function body. Well, at least one compiler
knows nothing of that. And then I will offer you an alternative
explanation requiring no magic at all.

[snip]


The behaviour of your (corrected) program is undefined in either case.

C89 draft 3.2.2.2:

"...If the number of arguments does not agree with the number of
parameters, the behavior is undefined."

C's () is not equivalent to C++'s (...).

--
Peter
Nov 14 '05 #16
Kevin Goodsell <us*********************@neverbox.com> wrote:
Richard Bos wrote:
Kevin Goodsell <us*********************@neverbox.com> wrote:
Richard Hunt wrote:

int main()

Prefer 'int main(void)'. "()" and "(void)" mean completely different
things in C.

No, they don't. This is a function _definition_, and in a function
definition sometype function() and sometype function(void) mean exactly
the same thing: function() is a function taking no arguments and
returning a value of type sometype.


While discussing this exact issue, somebody pointed out to me a while
back that

int main()
{
/*...*/
}

is both a definition *and* a declaration. Maybe I'm wrong (it's much too
late for me to go looking through the standard for a precise answer),
but my guess would be that, in the absence of a declaration that
provides more information (i.e., a prototype), the rules of a
declaration apply to the definition.


Hmmm... that _does_ sound logical, but it goes counter to what I've
always believed about function definitions.
_Inside_ the definition, of course, they are equivalent no matter what,
since there's no way to get at any arguments that may be provided.

Richard
Nov 14 '05 #17
Hi,

This will be out of topic, but I have something to say regarding the
casting in malloc.

Though the usual standards say that the casting in malloc is not
neccessary, I have found programs crashing with SIGILL, SIGBUS, and
SIGSEGV in my Solaris environment. This behaviour is when I use the 64
bit FORTE compiler to compile my code.

In my case, if the void pointer returned from Malloc is not casted to
the one assigned to, then the program crashes under high(sometimes
low) virtual memory consumption. Casting the void pointers have solved
lot of problems for me.

Strange thing is not all the void pointers I have not casted gives me
problems.
Its random.

Regards
Vishal

Kevin Goodsell <us*********************@neverbox.com> wrote in message news:<or*****************@newsread2.news.pas.earth link.net>...
Richard Hunt wrote:
I'm sorry for asking such a silly question, but I can't quite get my head
around malloc. Using gcc I have always programmed in a lax C/C++ hybrid
(which I suppose is actually c++). But I have started messing around in Plan
9, and that sort of thing is totally no go there :).

Is this correct to allocate memory for my struct? It works on my computer,
but I'm suspicious that I'm doing it wrong.


No, it's not correct. It shouldn't even compile. Here are the
diagnostics I got:

"C:\cygwin\bin\gcc.exe" -W -Wall -Wcast-align -Wwrite-strings
-Wno-sign-compare -Wno-unused-parameter -Wpointer-arith -ansi
-pedantic-errors -ggdb -c fun.c
fun.c:9: error: two or more data types in declaration of `main'
fun.c: In function `main':
fun.c:12: warning: implicit declaration of function `malloc'
fun.c:12: error: conversion to non-scalar type requested
fun.c:14: error: conversion to non-scalar type requested
fun.c:16: warning: implicit declaration of function `free'
Terminated with exit code 1

struct NODE;


This forward declaration is not useful.

struct NODE {
char string[80];
struct NODE *next;
}


fun.c:9: error: two or more data types in declaration of `main'

You missed a semicolon here.

int main()


Prefer 'int main(void)'. "()" and "(void)" mean completely different
things in C.
{
struct NODE *first;

first = (struct NODE) malloc(sizeof(struct NODE));


fun.c:12: warning: implicit declaration of function `malloc'

malloc has not been declared, so using it causes it to be implicitly
declared to return 'int'. This is wrong, and causes the behavior to be
undefined.
fun.c:12: error: conversion to non-scalar type requested

You've also cast to the wrong type.

You should probably not cast the return from malloc. It doesn't do
anything useful, makes maintenance more difficult, and can hide errors.
If you had cast to the correct type, and the compiler had not bothered
to warn about the implicit declaration of malloc (it's not required to,
and some don't), then you'd have a silent case of undefined behavior.

Finally, consider using the comp.lang.c-approved malloc idiom:

p = malloc(N * sizeof(*p));

This is less error-prone and more self-maintaining than other idioms.

first->next = (struct NODE) malloc(sizeof(struct NODE));


All the same problems as before, plus undefined behavior (probably
causing a crash) if the first malloc fails.

free(first);


Memory leak. You never freed first->next, and now you have no way to do so.

return 0;
}

Is it necessary to malloc the struct 'first'?


I'm not sure I know what you mean. 'first' is a pointer, not a struct.
It has to be made to point to something if you want it to be useful. A
malloced object is one possible choice.

In the context of this example, you didn't need malloc at all. You could
have done this:

struct NODE first, next;
first.next = next;

-Kevin

Nov 14 '05 #18
vi********@yahoo.com (imemyself) wrote:
This will be out of topic, but I have something to say regarding the
casting in malloc.

Though the usual standards say that the casting in malloc is not
neccessary, I have found programs crashing with SIGILL, SIGBUS, and
SIGSEGV in my Solaris environment. This behaviour is when I use the 64
bit FORTE compiler to compile my code.


Let me guess: you tend to forget to #include <stdlib.h>?

Richard
Nov 14 '05 #19
begin followup to Peter Nilsson:
Hope it wasn't your news client, that would be ironic.
Definitely not. Copy-n-paste fuckup.
My problem exists between mouse and chair.
But then I had to say that.
Sacrify ego or put blame on holy slrn?
For the true believer a no-brainer...
C89 draft 3.2.2.2:

"...If the number of arguments does not agree with the
number of parameters, the behavior is undefined."
Well, yes. The holy book. I guess that in there is also a special
rule about the many faces of main.

main(int,char**)
main(int,char**,char**)
main()
main(...)
main(void)

Ok, ok, that's heresy. Nowhere in the standard is written that
implementations of C follow the principle of logic and least
complicated design.

Stating that main is not a special case but just one instance
of a general principle might get bonus for scientific attitude,
but sure damnation by the high priests of ANSI.

Ok, ok, ANSI is always right, while my parody of a scientific
thesis breaks on a significant number of implementations.
For example on "gcc -mrtd".

The Hitchhikers Guide to the GCC has this to say about -mrtd:
# Use a different function-calling convention, in which functions
# that take a fixed number of arguments return with the `ret' NUM
# instruction, which pops their arguments while returning. This
# saves one instruction in the caller since there is no need to pop
# the arguments there.
C's () is not equivalent to C++'s (...).


Well, let's say that on the same platform they both will have
the same technical problem. In this way they are very equivalent.

--
Für Google, Tux und GPL!
Nov 14 '05 #20
Richard Bos wrote:

vi********@yahoo.com (imemyself) wrote:
This will be out of topic, but I have something to say regarding the
casting in malloc.

Though the usual standards say that the casting in malloc is not
neccessary, I have found programs crashing with SIGILL, SIGBUS, and
SIGSEGV in my Solaris environment.
This behaviour is when I use the 64
bit FORTE compiler to compile my code.


Let me guess: you tend to forget to #include <stdlib.h>?


Some programmers won't, #include stdlib.h
in a C file which uses stdlib functions,
if stdlib.h is already #included
in another header file for another C file,
which that C file, links with.

That's a mistake.

As the headers for other files,
evolve during the course of program developement,
whether or not the prototype for the function is still in scope
in the malloc using C file, changes,
and the programmer won't understand why.
Its random.


That one particular line, gives me a strong clue,
that that's how the inclusion of standard library headers
is being treated in your code.
It's a mistake.

--
pete
Nov 14 '05 #21
imemyself wrote:
Hi,
Please don't top-post. It's rude. Also, trim the message you are
replying to. Leave only the relevant section (or alternatively, write
your own short summary).

This will be out of topic, but I have something to say regarding the
casting in malloc.

Though the usual standards say that the casting in malloc is not
neccessary, I have found programs crashing with SIGILL, SIGBUS, and
SIGSEGV in my Solaris environment. This behaviour is when I use the 64
bit FORTE compiler to compile my code.
Then either the code was broken or the compiler was broken (experience
shows that the former is much more likely, but the latter is still
possible). This doesn't have much to do with what the best practice in C is.

In my case, if the void pointer returned from Malloc is not casted to
the one assigned to, then the program crashes under high(sometimes
low) virtual memory consumption. Casting the void pointers have solved
lot of problems for me.


All other things being equal, the cast should be a no-op (no difference
at run-time, it basically only effects what diagnostics the compiler
might issue).

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.
Nov 14 '05 #22
Richard Bos wrote:
vi********@yahoo.com (imemyself) wrote:

This will be out of topic, but I have something to say regarding the
casting in malloc.

Though the usual standards say that the casting in malloc is not
neccessary, I have found programs crashing with SIGILL, SIGBUS, and
SIGSEGV in my Solaris environment. This behaviour is when I use the 64
bit FORTE compiler to compile my code.

Let me guess: you tend to forget to #include <stdlib.h>?


The description of the problem didn't really sound consistent with that
error, at least to me. If the cast is needed to prevent run-time errors
rather than compile-time errors - well, that's just messed up. I want to
guess that malloc's memory pool has been corrupted, but that doesn't
quite sound right. The cast shouldn't fix that kind of error - it
shouldn't change anything at all (at run-time).

Maybe it's a compiler bug. If the description given is accurate, that
actually seems to be the most likely answer (even as unlikely as it
usually is, relatively speaking).

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.
Nov 14 '05 #23
On Mon, 29 Dec 2003 15:22:18 GMT, in comp.lang.c , pete
<pf*****@mindspring.com> wrote:
Some programmers won't, #include stdlib.h
in a C file which uses stdlib functions,
if stdlib.h is already #included
in another header file for another C file,
which that C file, links with.


I'm sure this has been mentioned before, but your line length is so
short its actually slightly hard to read - you seem to be writing in
either blank verse, or bad haikus.... Can I suggest selecting 65-70
chars as your wrap point, instead of around 40 chars?

--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
CLC readme: <http://www.angelfire.com/ms3/bchambless0/welcome_to_clc.html>
----== Posted via Newsfeed.Com - Unlimited-Uncensored-Secure Usenet News==----
http://www.newsfeed.com The #1 Newsgroup Service in the World! >100,000 Newsgroups
---= 19 East/West-Coast Specialized Servers - Total Privacy via Encryption =---
Nov 14 '05 #24
imemyself wrote:

Though the usual standards say that the casting in malloc is not
neccessary, I have found programs crashing with SIGILL, SIGBUS,
and SIGSEGV in my Solaris environment. This behaviour is when I
use the 64 bit FORTE compiler to compile my code.

In my case, if the void pointer returned from Malloc is not
casted to the one assigned to, then the program crashes under
high(sometimes low) virtual memory consumption. Casting the void
pointers have solved lot of problems for me.

Strange thing is not all the void pointers I have not casted
gives me problems.


Please don't toppost. It is not condoned in c.l.c., and is rude.

I think you have a well documented complaint to the compiler
vendor. It seems to be failing some of the most elementary
requirements. This assumes you have "#include <stdlib.h>", since
you show no code.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 14 '05 #25
Kevin Goodsell <us*********************@neverbox.com> wrote:
Richard Bos wrote:
vi********@yahoo.com (imemyself) wrote:
This will be out of topic, but I have something to say regarding the
casting in malloc.

Though the usual standards say that the casting in malloc is not
neccessary, I have found programs crashing with SIGILL, SIGBUS, and
SIGSEGV in my Solaris environment. This behaviour is when I use the 64
bit FORTE compiler to compile my code.


Let me guess: you tend to forget to #include <stdlib.h>?


The description of the problem didn't really sound consistent with that
error, at least to me.


Oh, I dunno. A lax compiler (or lax warning setting) combined with
illegal values being returned in the wrong register, or in the wrong
shape on the stack, sound like a reasonable cause for SIGSEGV and
plausibly SIGBUS as well, to me. Granted, SIGILL I can't figure out, but
still...

Richard
Nov 14 '05 #26
Richard Bos wrote:
Kevin Goodsell <us*********************@neverbox.com> wrote:

Richard Bos wrote:

vi********@yahoo.com (imemyself) wrote:
This will be out of topic, but I have something to say regarding the
casting in malloc.

Though the usual standards say that the casting in malloc is not
neccessary, I have found programs crashing with SIGILL, SIGBUS, and
SIGSEGV in my Solaris environment. This behaviour is when I use the 64
bit FORTE compiler to compile my code.

Let me guess: you tend to forget to #include <stdlib.h>?


The description of the problem didn't really sound consistent with that
error, at least to me.

Oh, I dunno. A lax compiler (or lax warning setting) combined with
illegal values being returned in the wrong register, or in the wrong
shape on the stack, sound like a reasonable cause for SIGSEGV and
plausibly SIGBUS as well, to me. Granted, SIGILL I can't figure out, but
still...


I don't really see that. Without <stdlib.h> and without a cast, a
diagnostic is required, right? OK, so the compiler could possibly get
this wrong (particularly if it is not invoked in strict
standard-compliance mode), or a warning could be issued and ignored. In
that case, run-time errors are a definite possibility. But a cast fixing
those errors? That I have a hard time understanding.

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.
Nov 14 '05 #27
On Sun, 28 Dec 2003 23:08:04 UTC, Kevin Goodsell
<us*********************@neverbox.com> wrote:

#define ALLOC(type) (type *)malloc(sizeof(type))


Makes bad things much bader. Whenever you frget to #include stdlib
your gets no warning but garbidge. malloc without prototyppe gets
interpreted as int mall() and this gets you code like:

1. call malloc
2. convert the value now in the place a function returned int to a
pointer of type the cast requires
3. later you'll dereference this garbidge - causing some undefined
behavior

Not every compiler uses one and the same location with exactly the
same number of bits for int and pointer to something.

So casting the return value <pointer to void> to something else means
invoking undefined behavior in any case even when the compiler does
send a diagnostic because YOU have forced the compiler to avoid any
diagnostic by telling him I KNOW THAT THE INT malloc returns IS in
reality a pointer - whereas it was YOU bug to avoid #include
<stdlib.h> - so the compiler will thing: "ok, the ill guy in front of
the screen knows that I can't know what malloc() does really, becaue
he has not telled me how to find the prototype. So I will assume that
it returns int and ignore anything that is on the place a function
returns void* has modified. It would be garbidge - but as the guy
tells me I will suppress any warning and transform that garbidge to be
a pointer of xy. Hopefully the program will crash some thousend lines
of source later."

Don't come with: but in C++.... because when you writes C++ then you
have to avoid the malloc family completely, you fave to use new/delete
instead.

--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation

Nov 14 '05 #28
On Mon, 29 Dec 2003 10:19:09 UTC, rl*@hoekstra-uitgeverij.nl (Richard
Bos) wrote:
Kevin Goodsell <us*********************@neverbox.com> wrote:
Richard Hunt wrote:
int main()
Prefer 'int main(void)'. "()" and "(void)" mean completely different
things in C.


No, they don't. This is a function _definition_, and in a function
definition sometype function() and sometype function(void) mean exactly
the same thing: function() is a function taking no arguments and
returning a value of type sometype.


No. int main() is a function with an incomplete list of parameters,
whereas int main(void) tells differently: no arguments accepted. An
incomplete list of parameters tells nothing about the number and types
of parameters - but allows both, any number of any types of actual
parameters.
What you say _is_ true for function declarations:

sometype function(void);

means: I have, somewhere, defined a function called function(), taking
no arguments, and returning a sometype; but

sometype function();

means: I have, somewhere, defined a function called function(),
returning a sometype, and I'm not telling you what kind of arguments it
takes.
But this is only true for declarations, not for definitions.

Richard


But int main() { is a definition! That means the calling point itself
has

int main() an unknown number of parameters with unknown types and
names. This is definitely something else than the definition of

int main(void) { a clearly written statement that says that NO
parameter is accepted.

Saying NONE is quite different from some unspezified number with some
unspezified types.

--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation

Nov 14 '05 #29
On Mon, 29 Dec 2003 14:13:25 UTC, vi********@yahoo.com (imemyself)
wrote:
Hi,

This will be out of topic, but I have something to say regarding the
casting in malloc.

Though the usual standards say that the casting in malloc is not
neccessary, I have found programs crashing with SIGILL, SIGBUS, and
SIGSEGV in my Solaris environment. This behaviour is when I use the 64
bit FORTE compiler to compile my code.

In my case, if the void pointer returned from Malloc is not casted to
the one assigned to, then the program crashes under high(sometimes
low) virtual memory consumption. Casting the void pointers have solved
lot of problems for me.

Strange thing is not all the void pointers I have not casted gives me
problems.
Its random.


You've forgot to announce the prototype of malloc() to the translation
unit! The compiler is NOT obligated to warn you on that fact anyway.
It is even not oblicated to give you an diganostic by

int a[10);
float f = a;

Even as this is rarely that what you would mean.

Whenever a compiler lets your code crash by

#include <stdlib>

int main(void) {
int *p = malloc(1000 * sizeof(*p));
.....

then your compiler is definitely NOT a C compiler - independant of
each conceivable platform.

Never use a C++ compiler to compile a C program - it won't work.
--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation

Nov 14 '05 #30
The Real OS/2 Guy wrote:
On Sun, 28 Dec 2003 23:08:04 UTC, Kevin Goodsell
<us*********************@neverbox.com> wrote:
#define ALLOC(type) (type *)malloc(sizeof(type))

Makes bad things much bader. Whenever you frget to #include stdlib
your gets no warning but garbidge. malloc without prototyppe gets
interpreted as int mall() and this gets you code like:


I'm well aware of that, thanks. (You probably could have figured that
out from the dozens of times I've explained that exact situation to
other people on this group.) All I was saying is that if you *really*
want/need to cast malloc's return for some reason (for example, if you
are writing in the common subset of C and C++), this method helps to
make sure that you cast to the same type that you allocate space for.

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.
Nov 14 '05 #31
The Real OS/2 Guy wrote:
On Sun, 28 Dec 2003 23:08:04 UTC, Kevin Goodsell
<us*********************@neverbox.com> wrote:
#define ALLOC(type) (type *)malloc(sizeof(type))

Makes bad things much bader. Whenever you frget to #include stdlib
your gets no warning but garbidge. malloc without prototyppe gets
interpreted as int mall() and this gets you code like:

1. call malloc
2. convert the value now in the place a function returned int to a
pointer of type the cast requires
3. later you'll dereference this garbidge - causing some undefined
behavior

Not every compiler uses one and the same location with exactly the
same number of bits for int and pointer to something.

So casting the return value <pointer to void> to something else means
invoking undefined behavior in any case even when [...]


I hope you're not saying here that casting a void* to another pointer
type is UB (just checking).
the compiler does
send a diagnostic because YOU have forced the compiler to avoid any
diagnostic by telling him I KNOW THAT THE INT malloc returns IS in
reality a pointer - whereas it was YOU bug to avoid #include
<stdlib.h> - so the compiler will thing: "ok, the ill guy in front of
the screen knows that I can't know what malloc() does really, becaue
he has not telled me how to find the prototype. So I will assume that
it returns int and ignore anything that is on the place a function
returns void* has modified. It would be garbidge - but as the guy
tells me I will suppress any warning and transform that garbidge to be
a pointer of xy. Hopefully the program will crash some thousend lines
of source later."

Don't come with: but in C++.... because when you writes C++ then you
have to avoid the malloc family completely,
"have to?" Says who? It's perfectly well-defined.
you fave to use new/delete instead.


Best regards,

Sidney

Nov 14 '05 #32
On Sun, 4 Jan 2004 22:40:54 UTC, Sidney Cadot <si****@jigsaw.nl>
wrote:
I hope you're not saying here that casting a void* to another pointer
type is UB (just checking).


No, I'm saying that cating the return value of a function that returns
pointer to void is going to be UB when the prototype of the fuction is
not visible to the compiler.

I say further that casting a pointer to void to something else is
completely useless.
--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation

Nov 14 '05 #33
On Sun, 4 Jan 2004 19:06:49 UTC, Kevin Goodsell
<us*********************@neverbox.com> wrote:
The Real OS/2 Guy wrote:
On Sun, 28 Dec 2003 23:08:04 UTC, Kevin Goodsell
<us*********************@neverbox.com> wrote:
#define ALLOC(type) (type *)malloc(sizeof(type))

Makes bad things much bader. Whenever you frget to #include stdlib
your gets no warning but garbidge. malloc without prototyppe gets
interpreted as int mall() and this gets you code like:


I'm well aware of that, thanks. (You probably could have figured that
out from the dozens of times I've explained that exact situation to
other people on this group.) All I was saying is that if you *really*
want/need to cast malloc's return for some reason (for example, if you
are writing in the common subset of C and C++), this method helps to
make sure that you cast to the same type that you allocate space for.

-Kevin


There is absolutely no reason to compile C with a C++ compiler. Or
likes you to compile C with a Cobol, Fortran or Pascal compiler too?

Either you use malloc - then you have to use a C compiler or you use
new - that is the equivalent of C++.

Or you have a programming logic that is generelly errornpus because
you are unable to make a well defined program design.

Make a well design of your program - and you will never use a C++
compiler to compile C because there are other methods to get C
functions called from C++ without recompiling them with a compiler
that is not designed to do so.

--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation

Nov 14 '05 #34
The Real OS/2 Guy wrote:

There is absolutely no reason to compile C with a C++ compiler. Or
likes you to compile C with a Cobol, Fortran or Pascal compiler too?


Maybe you should go back and read P.J. Plauger's posts on the subject.
Clearly some people *do* find reasons to compile C with a C++ compiler.
Personally I've never had a good reason to do so, but that doesn't mean
that reasons don't exist.

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.
Nov 14 '05 #35

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

13
by: Richard | last post by:
vector<char*> m_Text; m_Text.resize(1); char* foo = "FOO"; char* bar = "BAR"; char* foobar = (char*)malloc(strlen(foo) + strlen(bar) + 1); if (foobar) { strcpy(foobar, foo); strcat(foobar,...
2
by: dam_fool_2003 | last post by:
My understanding about wrapping is that we add utilities to a lib function for our specific use. So days ago in the c.l.c I saw a function def as: void * xmalloc (size_t size) { register void...
20
by: mechanicfem | last post by:
I thought (as they're in c99) that flexible arrays were there for a number of reasons - but I also thought they'd be great for stepping into structures (say) that were aligned in memory after (say)...
1
by: hello12 | last post by:
hello, I am supposed to concatenate 2 strings (words). For this the function should call malloc or calloc to get memory for the newstring(after concatenated) .I am not allowed to use the library...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.