Richard said:
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
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.
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.
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