structs

B

Bill Cunningham

The code here,
http://www.java2s.com/Code/C/Structure/Pointingoutthehorsesallocatememoryforstruct.htm

Confuses me in some places. *pcats[50] must mean the most number of cats
possible to put into the struct is 50. Then farther into the code
pcat[hcount] shows up. hcount is a count iterator of course. That I can see.
The code compiles and runs good and does what is expected. I am just used to
putting into the struct something like

struct cat *next

for the next page which would be about another cat. How could I get the
above to work in this example?

Bill
 
K

Keith Thompson

Bill Cunningham said:
The code here,
http://www.java2s.com/Code/C/Structure/Pointingoutthehorsesallocatememoryforstruct.htm

Confuses me in some places. *pcats[50] must mean the most number of cats
possible to put into the struct is 50. Then farther into the code
pcat[hcount] shows up. hcount is a count iterator of course. That I can see.
The code compiles and runs good and does what is expected. I am just used to
putting into the struct something like

struct cat *next

for the next page which would be about another cat. How could I get the
above to work in this example?

To answer your question, the code uses a fixed-size array of pointers
to structs. There's no need for a "next" link in each structure;
you can traverse all the existing structures just by traversing
the array.

But you should be aware that the code is really bad in places.

It uses repeated "magic numbers" rather than declared constants.

It uses "void main()".

It prints a yes-or-no prompt and treats any answer other than 'n' or
'N' to mean yes. Note in particular that an end-of-file condition
will treated as a yes response.

It casts the result of malloc and doesn't check the result.

It uses scanf() with a "%s" format; if you enter a name longer than 20
characters, you get undefined behavior.

It doesn't check the result of scanf().

It doesn't check for end-of-file or input errors.
 
B

Bill Cunningham

To answer your question, the code uses a fixed-size array of pointers
to structs. There's no need for a "next" link in each structure;
you can traverse all the existing structures just by traversing
the array.

But you should be aware that the code is really bad in places.

It uses repeated "magic numbers" rather than declared constants.

It uses "void main()".

My compiler complained of that.
 
B

Bill Cunningham

Here's my pathetic attempt at trying this code. Over the last few weeks
I've learned about pointers by diving into code and reading. I've been
working with networking system calls and honing some pointer skill. But this
has got me stuck. I never really use malloc and don't understand its need on
modern processors.

#include <stdio.h>
#include <stdlib.h>

struct cat {
char *name;
char *color;
int age;
char sex;
struct cat *next;
};
struct cat k, *p;
(struct cat *) p = malloc(sizeof struct cat);
memset(&k, 0, sizeof k);

p.c:12: error: syntax error before "struct"
p.c:13: error: syntax error before '&' token
p.c:13: warning: conflicting types for built-in function 'memset'
p.c:13: warning: data definition has no type or storage class

Now I would say that since malloc returns void* it would return any
pointer. Why not a pointer to type struct cat ? I would like a function that
would load up this struct and then I could use for or an array to go through
pages.

Bill
 
K

Keith Thompson

Bill Cunningham said:
Here's my pathetic attempt at trying this code.

No argument there.

[...]
#include <stdio.h>
#include <stdlib.h>

struct cat {
char *name;
char *color;
int age;
char sex;
struct cat *next;
};
struct cat k, *p;

Why are these global? Why not declare them locally to some function?
(struct cat *) p = malloc(sizeof struct cat);

Oh, I see, you didn't bother to write a function. Does the name "main"
ring a bell?

Statements cannot appear outside function definitions, as you've
been told many times before. This is part of the reason you're
getting a syntax error. The other part is that the statement is
wrong on multiple levels (cast on LHS of assignment, wrong syntax
for sizeof). The recommended idiom for calling malloc has been
posted here about a bajillion times.

p = malloc(sizeof *p);

Of course you need to check the result, and decide what to do if
malloc() fails.
memset(&k, 0, sizeof k);

What exactly do you expect this to accomplish? It sets the contents
of k to all-bits-zero, but why do you want to do that?

[...]

Your code is (loosely) based on an example you found on the web
somewhere. I already listed multiple serious flaws in that code.
My advice: Stop trying to use code from that site. A experienced
programmer can take bad code, correct its flaws, and turn it into
good code, but I don't believe you can do so. So far, you've just
made a bigger mess of it. Find yourself some *good* existing code
(maybe someone else can recommend a site) and start with that.
 
I

Ian Collins

Here's my pathetic attempt at trying this code. Over the last few weeks
I've learned about pointers by diving into code and reading. I've been
working with networking system calls and honing some pointer skill. But this
has got me stuck. I never really use malloc and don't understand its need on
modern processors.

#include<stdio.h>
#include<stdlib.h>

struct cat {
char *name;
char *color;
int age;
char sex;
struct cat *next;
};
struct cat k, *p;
(struct cat *) p = malloc(sizeof struct cat);
memset(&k, 0, sizeof k);

p.c:12: error: syntax error before "struct"
p.c:13: error: syntax error before '&' token
p.c:13: warning: conflicting types for built-in function 'memset'
p.c:13: warning: data definition has no type or storage class

Oh come on Bill, you've only recently used that troll on c.u.p. Try
something original next time.
 
B

Bill Cunningham

Keith said:
No argument there.

[...]
#include <stdio.h>
#include <stdlib.h>

struct cat {
char *name;
char *color;
int age;
char sex;
struct cat *next;
};
struct cat k, *p;

Why are these global? Why not declare them locally to some function?

If I amd going to do something simple like this (and I see I did forget
Oh, I see, you didn't bother to write a function. Does the name
"main" ring a bell?

Statements cannot appear outside function definitions, as you've
been told many times before. This is part of the reason you're
getting a syntax error. The other part is that the statement is
wrong on multiple levels (cast on LHS of assignment, wrong syntax
for sizeof). The recommended idiom for calling malloc has been
posted here about a bajillion times.

p = malloc(sizeof *p);

Of course you need to check the result, and decide what to do if
malloc() fails.


What exactly do you expect this to accomplish? It sets the contents
of k to all-bits-zero, but why do you want to do that?

I've gotten into the habit of declaring and defining like memset above
or int a=0; or char a='\0';
Your code is (loosely) based on an example you found on the web
somewhere. I already listed multiple serious flaws in that code.

You mentioned that in that code the person used 'n' or 'N' for example.
I think concerning the point he was trying to get across was malloc he might
have shortcutted where he did to save time get the point across and came up
with sub-standard code. I could be wrong though. So I kind of waded through
it.
My advice: Stop trying to use code from that site. A experienced
programmer can take bad code, correct its flaws, and turn it into
good code, but I don't believe you can do so. So far, you've just
made a bigger mess of it. Find yourself some *good* existing code
(maybe someone else can recommend a site) and start with that.

Exactly. I would trust myself to decided what is good or not.

Also remember I am using the same struct examples I used a long time ago to
get structs. The cat example. I've picked up some.
What I'm going for is a function that loads up the struct with examples
and I might try something like.

struct cat *p;
struct cat *pp;

for (pp=p;p!=NULL;pp->next)...

Bill
 
B

Bill Cunningham

I have this code here now that compiles and assembles fine. I get an object
code from it. I am trying to create a function that takes the data on each
cat and loads it into the struct.

#include <stdio.h>
#include <stdlib.h>

struct cat {
char *name;
char *color;
int age;
char sex;
struct cat *next;
};

struct cat *load(char *n, char *c, int a, char s, struct cat *next)
{
struct cat k;
memset(&k, 0, sizeof k);
k.name = n;
k.color = c;
k.age = a;
k.sex = s;
}

I don't need anything to be static there will only be this one file with the
load() and main. Unless that is changed. The compiler wants to know the size
of k so I set memset. Each cat is a "page" and I don't know how to use that
last parameter of the load function.
 
B

Bill Cunningham

Geoff said:
You forgot to build your program properly, as Keith has pointed out.

I don't know what compiler you are using but you appear to be using a
command line tool to build your programs. I'd recommend if you want to
learn C that you use a tool like Microsoft Visual C since it allows
you to debug your program and look a the variables as you learn what
each statement does. GCC and GDB are rather novice-intolerant and you
appear to be running on Windows anyway. Visual C++ Express Edition is
free.

I strongly urge you to write your programs with a consistent style and
to single-step your samples and examine the data as they execute.

I also advise you to comment your code as you write it. This way you
can explain to yourself what you think you are doing and see if you
can write the code that supports that concept. Since you are studying
the language, over-commenting is perfectly OK.

To the end that you can understand the principle of structures I offer
the following:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* define the structure of cat */
struct cat {
char *name;
char *color;
int age;
char sex;
struct cat *next;
};

/* define the main function */
int main(void)
{
/* avoid use of comma in variable declarations */
struct cat k; /* a local instance of struct cat */
struct cat *p; /* a pointer to a cat to be allocated later */

/* allocate a struct cat, via p */
/* since p points to stuct cat, the compiler knows its size */
p = malloc(sizeof *p);

/* ALWAYS check the return value of malloc() */
if (p == NULL)
{
printf("Memory allocation failed.\n");
exit(EXIT_FAILURE);
}

/* initialize the contents of the new cat instance */
/* members can be accessed in any order */
p->name = "Kitty";
p->color = "Calico";
p->age = 10;
p->sex = 'F';
p->next = &k; /* point to the next cat */

/* initialize the contents of the local cat */
memset(&k, 0, sizeof k);

/* put new data into it */
k.name = "Puff";
k.color = "White";
k.age = 10;
k.sex = 'M';
k.next = NULL;

free(p); /* free the allocated memory */
return 0;
}

Ok Geoff I will work with this. I understand what you are doing. But how
would you load that struct with your cats by function? A parameter would
take each part of your data and manipulate it and store it in memory. I see
memset is needed here so the compiler can know the size of struct cat.

I use windows for networking on the internet and linux for development
and have been studying *nix networking lately. The compiler is a somewhat
aged 3.4.6 gcc I use from linux's shell.

Bill
 
B

Bill Cunningham

Keith said:
Nonsense.

Ok Keith. My compiler complained about not knowing the size and when I
added memset() it appeared to me to change something. Something was
different anyway. What I want to do here next is pass those pointers Geoff
mentions as parameters to a function that loads the struct.

Bill
 
K

Keith Thompson

Bill Cunningham said:
Ok Keith. My compiler complained about not knowing the size and when I
added memset() it appeared to me to change something. Something was
different anyway. What I want to do here next is pass those pointers Geoff
mentions as parameters to a function that loads the struct.

You added something random, and something changed. You're guessing.
How well has that worked for you in the past?

If the compiler stopped complaining about not knowing the size of
something, it must have been because of some other change you made
at the same time.

As long as you make random changes like this without understanding
why you're making them, you will never learn. There are languages
in which making the compiler happy (no warnings or error messages)
means, for small simple programs, that there's a reasonably good
chance your code is correct. C is not one of those languages.
 
J

jacob navia

Ian Collins a écrit :
On 05/24/10 05:56 AM, Bill Cunningham wrote:
snip

Oh come on Bill, you've only recently used that troll on c.u.p. Try
something original next time.

Interesting that he never answers this messages...
Neither yours nor mine...

Why Mr Cunningham?
 
N

Nick Keighley

I have this code here now that compiles and assembles fine. I get an object
code from it. I am trying to create a function that takes the data on each
cat and loads it into the struct.

#include <stdio.h>
#include <stdlib.h>

struct cat {
    char *name;
    char *color;
    int age;
    char sex;
    struct cat *next;

};

struct cat *load(char *n, char *c, int a, char s, struct cat *next)
{
    struct cat k;

what's the point of modifying a local variable?
    memset(&k, 0, sizeof k);

you never answered Keith's question. Why are you doing this. Note
memset()ing a pointer to all zeros MAY NOT correctly set a pointer to
a valid value. If you want to initialise a struct to default values
why not use

struct cat k = {0};

though, annoyingly some compilers give warnings.
    k.name = n;
    k.color = c;
    k.age = a;
    k.sex = s;

}

I don't need anything to be static there will only be this one file with the
load() and main. Unless that is changed. The compiler wants to know the size
of k so I set memset.

why does "the compiler want to know the size of k"? how does "setting
memset" tell it? what is the connection between a simple call of
memset() and "setting memset"? what does "setting memset" mean?

Each cat is a "page"

what's a "page"

and I don't know how to use that
last parameter of the load function.

struct cat *load(char *n, char *c, int a, char s, struct cat *next)
{
struct cat k;
memset(&k, 0, sizeof k);
k.name = n;
k.color = c;
k.age = a;
k.sex = s;
k.next = next;
}

you probably need to pass k as a parameter to load(). Do you
understand what a linked list is?


QUESTION ZERO: WHAT ARE YOU TRYING TO DO?


before you write a single line of code you answer this question. You
are like a perseon that starts walking in a random direction then
decides where to go after walking for a bit. Or, in your case, doesn't
decide.
 
N

Nick Keighley

Keith Thompson wrote:

don't snip useful context

Bill Cunningham said:
***
I see memset is needed here so the compiler can know the size of
struct cat.
***

"bollocks" was my thought
    Ok Keith. My compiler complained about not knowing the size and when I
added memset() it appeared to me to change something. Something was
different anyway. What I want to do here next is pass those pointers Geoff
mentions as parameters to a function that loads the struct.

stop "programming by guessing". Post the code that the compiler
complained about. memset()doesn't tell the compiler the size of
anything



--

You are in a clearing. You can see a spire in the distance.
You can also see a copy of "C Unleashed".
: INV
You have;
a DeathStation 900 laptop,
a voucher for a free pizza,
and a torch.
: TAKE BOOK
You can't. It's too heavy.
Bill Godfrey (clc)
 
B

BruceS

On May 25, 1:25 am, Nick Keighley <[email protected]>
wrote:
--

You are in a clearing. You can see a spire in the distance.
You can also see a copy of "C Unleashed".
: INV
You have;
 a DeathStation 900 laptop,
 a voucher for a free pizza,
 and a torch.
: TAKE BOOK
You can't. It's too heavy.
    Bill Godfrey (clc)

What if it were a copy of CTCR? Would it also be too heavy, because
the it's so demonstrably dense, or not, because it's full of hot air?
EMWTK.
 
B

Bill Cunningham

stop "programming by guessing". Post the code that the compiler
complained about. memset()doesn't tell the compiler the size of
anything

The way I understand it memset() sets all the elements in the struct in
this case to whateve the second parameter is. Be it '0' or '\0' which I have
also used before. I thought there might also be a mechanism that is "malloc
like" in setting a size. I see memset doesn't work like that.

Bill
 
K

Keith Thompson

Bill Cunningham said:
stop "programming by guessing". Post the code that the compiler
complained about. memset()doesn't tell the compiler the size of
anything

The way I understand it memset() sets all the elements in the struct in
this case to whateve the second parameter is. Be it '0' or '\0' which I have
also used before. I thought there might also be a mechanism that is "malloc
like" in setting a size. I see memset doesn't work like that.

Please stop posting using Microsoft Outlook Express. There's
supposed to be a way to get it to quote properly, but obviously
it's not working for you. You've used a different newsreader
(Thunderbird?) in the past, and it worked just fine.

memset() sets each *byte*, not each element, to 0. (And of course
'0' and '\0' are very different things).

What on Earth do you mean by "setting a size"? The size of what?
What is it that has a size that you think the compiler doesn't
already know about? Forget about memset(); what problem are you
trying to solve?
 
B

Bill Cunningham

Keith said:
Please stop posting using Microsoft Outlook Express. There's
supposed to be a way to get it to quote properly, but obviously
it's not working for you. You've used a different newsreader
(Thunderbird?) in the past, and it worked just fine.

I've been using quotefix. Maybe I've opened OE and not went through
quotefix.
memset() sets each *byte*, not each element, to 0. (And of course
'0' and '\0' are very different things).

What on Earth do you mean by "setting a size"? The size of what?

I misspoke I meant clearing the size of garbage.
What is it that has a size that you think the compiler doesn't
already know about? Forget about memset(); what problem are you
trying to solve?
http://www.taranets.com/cgi/ts/1.37/ts.ws.pl?w=329;b=282

This looks somewhat better. There is a function that prints the name data
stored. A database of sorts.

With the mentioned structures in previous posts I would like

int load(struct cat *);

To load the structure. I also want a function to print out data stored in
memory. Maybe I should pursue this method at all,

k.age=5;

But just p->age=5;

Then my next task would be storing the data in memory to disk. But
that's another story...

Bill
 

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

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top