473,406 Members | 2,954 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,406 software developers and data experts.

Recursive structure?

I've come a across a program that declares the following data
structure.

typedef struct node {
struct node *next;
} node;

It looks like a recursive data structure but I'm having trouble
understanding the use of it? Can somebody explain this?

How much memory will be allocated by the compiler when the structure is
instantiated?

The following structure makes use of the previous structure.

typedef struct queue {
node *head, *tail;
} queue;

Best regards!

Aug 9 '06 #1
20 8769
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
dspfun wrote:
I've come a across a program that declares the following data
structure.

typedef struct node {
struct node *next;
} node;

It looks like a recursive data structure
Not really, but you /are/ close. First off, the quoted text isn't a
structure, it is a typedef. A typedef defines a name that will be
associated to a simple or complex storage type. In this case, the type
associated to the name "node' just happens to be a structure definition
called "node".
but I'm having trouble
understanding the use of it? Can somebody explain this?
Sure.

Assuming that you are concerned about the
struct node {
struct node *next;
};
portion of the typedef, then the structure definition called "node"
contains a /pointer/ (of the type "pointer to struct node").
How much memory will be allocated by the compiler when the structure is
instantiated?
First off, "instantiation" isn't the term to use. But, I know what you
mean.

How much memory?? Well, it will be
sizeof(struct node)
bytes long.

What's the "real" value, you ask? We can't tell you, other than to say
that it will be at least big enough to hold a pointer to a structure.
The structure /may/ be allocated with invisible padding/alignment
bytes, making the structure bigger than the sum of it's components, but
that's up to the compiler to determine. Also, depending on your
compiler, a pointer to struct node may be larger, smaller, or the same
size as any other pointer. Again, this is implementation dependant.

[snip]
HTH

- --
Lew Pitcher

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.3 (MingW32) - WinPT 0.11.12

iD8DBQFE2fYCagVFX4UWr64RAsvqAKDoqBMdCETJhrKiFqbcTj 1h7mwKBwCg4MMf
esqUVrmtlZg6juKjuZpIHV8=
=ERDL
-----END PGP SIGNATURE-----

Aug 9 '06 #2

Lew Pitcher wrote:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
dspfun wrote:
I've come a across a program that declares the following data
structure.

typedef struct node {
struct node *next;
} node;

It looks like a recursive data structure

Not really, but you /are/ close. First off, the quoted text isn't a
structure, it is a typedef. A typedef defines a name that will be
associated to a simple or complex storage type. In this case, the type
associated to the name "node' just happens to be a structure definition
called "node".
but I'm having trouble
understanding the use of it? Can somebody explain this?

Sure.

Assuming that you are concerned about the
struct node {
struct node *next;
};
portion of the typedef, then the structure definition called "node"
contains a /pointer/ (of the type "pointer to struct node").
Yes, this is exactly what I don't understand, how can "structure node"
contain a pointer of the type "pointer to struct node"? It seems that
"struct node" is not declared readily? How can the compiler know what
to do? To me it seems analogous to saying "x has the value x".
How much memory will be allocated by the compiler when the structure is
instantiated?

First off, "instantiation" isn't the term to use. But, I know what you
mean.

How much memory?? Well, it will be
sizeof(struct node)
bytes long.

What's the "real" value, you ask? We can't tell you, other than to say
that it will be at least big enough to hold a pointer to a structure.
The structure /may/ be allocated with invisible padding/alignment
bytes, making the structure bigger than the sum of it's components, but
that's up to the compiler to determine. Also, depending on your
compiler, a pointer to struct node may be larger, smaller, or the same
size as any other pointer. Again, this is implementation dependant.

[snip]
HTH

- --
Lew Pitcher

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.3 (MingW32) - WinPT 0.11.12

iD8DBQFE2fYCagVFX4UWr64RAsvqAKDoqBMdCETJhrKiFqbcTj 1h7mwKBwCg4MMf
esqUVrmtlZg6juKjuZpIHV8=
=ERDL
-----END PGP SIGNATURE-----
Aug 9 '06 #3

dspfun wrote:
Yes, this is exactly what I don't understand, how can "structure node"
contain a pointer of the type "pointer to struct node"? It seems that
"struct node" is not declared readily? How can the compiler know what
to do? To me it seems analogous to saying "x has the value x".
Ah, quite perceptive of you. But it does work because:

(1) What's included is a POINTER to a variable of the same type.

(2) On most every system I can think of, except perhaps some weird ol
Burroughs, a POINTER is just an address. And the address of anything,
no matter what the size, shape or type of the thing, the address is
just a fixed number of bits, often 16, 32, 48, or 64 bits.

(3) So when the compiler sees: struct foo{ foo * nextfoo; it goes
"okay, foo hasnt been fully declared yet, in fact, I may not even be
aware that there is a foo being declared, but a pointer to anything is
just 32 bits, I know how to allocate that"

(4) Eventually foo will come to an end and everything will be okay.

----

It can get even a bit more abstract, you can define ahead of time:

typedef foo * PtrToFoo;

and that will be accepted, as the compiler "knows" you may be intending
to do the same thing as above. of course eventually the base type has
to be defined somewheere.

Aug 9 '06 #4

"dspfun" <ds****@hotmail.comha scritto nel messaggio
news:11**********************@i3g2000cwc.googlegro ups.com...
>
Lew Pitcher wrote:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
dspfun wrote:
I've come a across a program that declares the following data
structure.
>
typedef struct node {
struct node *next;
} node;
>
It looks like a recursive data structure
Not really, but you /are/ close. First off, the quoted text isn't a
structure, it is a typedef. A typedef defines a name that will be
associated to a simple or complex storage type. In this case, the type
associated to the name "node' just happens to be a structure definition
called "node".
but I'm having trouble
understanding the use of it? Can somebody explain this?
Sure.

Assuming that you are concerned about the
struct node {
struct node *next;
};
portion of the typedef, then the structure definition called "node"
contains a /pointer/ (of the type "pointer to struct node").

Yes, this is exactly what I don't understand, how can "structure node"
contain a pointer of the type "pointer to struct node"? It seems that
"struct node" is not declared readily? How can the compiler know what
to do? To me it seems analogous to saying "x has the value x".
No. It is different.
If you say "struct x" I don't know the size, but
if you say (struct x *) I know the size, representation
and alignment, for each 'x'.

--
Giorgio Silvestri
DSP/Embedded/Real Time OS Software Engineer


Aug 9 '06 #5
dspfun wrote:

Lew Pitcher wrote:
>Assuming that you are concerned about the
struct node {
struct node *next;
};
portion of the typedef, then the structure definition called "node"
contains a /pointer/ (of the type "pointer to struct node").

Yes, this is exactly what I don't understand, how can "structure node"
contain a pointer of the type "pointer to struct node"?
Why could it not?
It seems that
"struct node" is not declared readily?
Doesn't matter: the compiler knows how to do a /pointer/ to /any/ struct.

If it said `struct node { struct node infinite; };` then there would
be a problem.

--
Chris "seeker" Dollin
A rock is not a fact. A rock is a rock.

Aug 9 '06 #6

Chris Dollin wrote:
dspfun wrote:

Lew Pitcher wrote:
Assuming that you are concerned about the
struct node {
struct node *next;
};
portion of the typedef, then the structure definition called "node"
contains a /pointer/ (of the type "pointer to struct node").
Yes, this is exactly what I don't understand, how can "structure node"
contain a pointer of the type "pointer to struct node"?

Why could it not?
It seems that
"struct node" is not declared readily?

Doesn't matter: the compiler knows how to do a /pointer/ to /any/ struct.

If it said `struct node { struct node infinite; };` then there would
be a problem.

--
Chris "seeker" Dollin
A rock is not a fact. A rock is a rock.
I understand now that the compiler knows how to do a pointer to /any/
struct.

But, if I declare:
node *mynode;

Then I have declared a pointer to a node struct. But all node struct
contains is a pointer to a node struct. I can't see anything useful
with this, however, since it is used it must be good for something.

Can someone give some example of what this (mynode pointer) is good
for?

Wouldn't it be equally good to declare node struct like this?:

struct node {
void *next;
};

Aug 9 '06 #7
dspfun (in 11**********************@75g2000cwc.googlegroups.c om) said:

| Chris Dollin wrote:
|| dspfun wrote:
||
||
||| Lew Pitcher wrote:
|||| Assuming that you are concerned about the
||||| struct node {
||||| struct node *next;
||||| };
|||| portion of the typedef, then the structure definition called
|||| "node" contains a /pointer/ (of the type "pointer to struct
|||| node").
||||
|||
||| Yes, this is exactly what I don't understand, how can "structure
||| node" contain a pointer of the type "pointer to struct node"?
||
|| Why could it not?
||
||| It seems that
||| "struct node" is not declared readily?
||
|| Doesn't matter: the compiler knows how to do a /pointer/ to /any/
|| struct.
||
|| If it said `struct node { struct node infinite; };` then there
|| would
|| be a problem.
|
| I understand now that the compiler knows how to do a pointer to
| /any/ struct.
|
| But, if I declare:
| node *mynode;
|
| Then I have declared a pointer to a node struct. But all node struct
| contains is a pointer to a node struct. I can't see anything useful
| with this, however, since it is used it must be good for something.
|
| Can someone give some example of what this (mynode pointer) is good
| for?

It's not unusual to see something like:

node *head; /* Pointer to first element */
node *tail; /* Pointer to final element */

or even:

struct
{ node *head;
node *tail;
} mylist;

to provide a "root" for a list.

| Wouldn't it be equally good to declare node struct like this?:
|
| struct node {
| void *next;
| };

Certainly.

--
Morris Dovey
DeSoto Solar
DeSoto, Iowa USA
http://www.iedu.com/DeSoto
Aug 9 '06 #8
Morris Dovey (in 44***********************@news.qwest.net) said:

| dspfun (in 11**********************@75g2000cwc.googlegroups.c om)
| said:
|
|| struct node {
|| void *next;
|| };
|
| Certainly.

Oops! I missed the 'void'. It would _not_ be better.

--
Morris Dovey
DeSoto Solar
DeSoto, Iowa USA
http://www.iedu.com/DeSoto
Aug 9 '06 #9

Morris Dovey wrote:
dspfun (in 11**********************@75g2000cwc.googlegroups.c om) said:

| Chris Dollin wrote:
|| dspfun wrote:
||
||
||| Lew Pitcher wrote:
|||| Assuming that you are concerned about the
||||| struct node {
||||| struct node *next;
||||| };
|||| portion of the typedef, then the structure definition called
|||| "node" contains a /pointer/ (of the type "pointer to struct
|||| node").
||||
|||
||| Yes, this is exactly what I don't understand, how can "structure
||| node" contain a pointer of the type "pointer to struct node"?
||
|| Why could it not?
||
||| It seems that
||| "struct node" is not declared readily?
||
|| Doesn't matter: the compiler knows how to do a /pointer/ to /any/
|| struct.
||
|| If it said `struct node { struct node infinite; };` then there
|| would
|| be a problem.
|
| I understand now that the compiler knows how to do a pointer to
| /any/ struct.
|
| But, if I declare:
| node *mynode;
|
| Then I have declared a pointer to a node struct. But all node struct
| contains is a pointer to a node struct. I can't see anything useful
| with this, however, since it is used it must be good for something.
|
| Can someone give some example of what this (mynode pointer) is good
| for?

It's not unusual to see something like:

node *head; /* Pointer to first element */
node *tail; /* Pointer to final element */

or even:

struct
{ node *head;
node *tail;
} mylist;

to provide a "root" for a list.
I'm probably missing something here because I don't see what the
purpose of such a list would be, all it is is a list of node pointers,
isn't it? What is the use of such a list? Wouldn't one like to have
some data at each entry of a list?
| Wouldn't it be equally good to declare node struct like this?:
|
| struct node {
| void *next;
| };

Certainly.

--
Morris Dovey
DeSoto Solar
DeSoto, Iowa USA
http://www.iedu.com/DeSoto
Aug 9 '06 #10

dspfun wrote:
I'm probably missing something here because I don't see what the
purpose of such a list would be, all it is is a list of node pointers,
isn't it? What is the use of such a list? Wouldn't one like to have
some data at each entry of a list?

Which is easier to carry around:
(1) The key to your house.

(2) Your house.

Aug 9 '06 #11
"dspfun" <ds****@hotmail.comwrites:
Morris Dovey wrote:
[...]
>It's not unusual to see something like:

node *head; /* Pointer to first element */
node *tail; /* Pointer to final element */

or even:

struct
{ node *head;
node *tail;
} mylist;

to provide a "root" for a list.

I'm probably missing something here because I don't see what the
purpose of such a list would be, all it is is a list of node pointers,
isn't it? What is the use of such a list? Wouldn't one like to have
some data at each entry of a list?
Yes, absolutely. A linked list with no actual data isn't much use,
except as a demonstration.

Possibly Morris thought that adding an extra "payload" member would
distract from the main point.

--
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.
Aug 9 '06 #12
Keith Thompson (in ln************@nuthaus.mib.org) said:

| "dspfun" <ds****@hotmail.comwrites:
|| Morris Dovey wrote:
| [...]
||| It's not unusual to see something like:
|||
||| node *head; /* Pointer to first element */
||| node *tail; /* Pointer to final element */
|||
||| or even:
|||
||| struct
||| { node *head;
||| node *tail;
||| } mylist;
|||
||| to provide a "root" for a list.
||
|| I'm probably missing something here because I don't see what the
|| purpose of such a list would be, all it is is a list of node
|| pointers, isn't it? What is the use of such a list? Wouldn't one
|| like to have some data at each entry of a list?
|
| Yes, absolutely. A linked list with no actual data isn't much use,
| except as a demonstration.
|
| Possibly Morris thought that adding an extra "payload" member would
| distract from the main point.

You can get a glimpse of my tortured thought processes in
http://www.iedu.com/mrd/c/queue.c

I'm inclined to define elements (nodes) like:

typedef struct element_d
{ struct element_d *link;
/* Payload data */
} element;

and then declare a list control structure (without payload):

struct
{ element *head;
element *tail;
} some_list = { NULL,NULL };

because it's not unusual for me to have several lists being
manipulated within the same application. It's generally more
economical to pass a pointer to some_list in one situation; or to pass
a pointer to some_other_list elsewhere so that a set of common list
manipulation functions can massage either list.

--
Morris Dovey
DeSoto Solar
DeSoto, Iowa USA
http://www.iedu.com/DeSoto
Aug 9 '06 #13

Morris Dovey wrote:
Keith Thompson (in ln************@nuthaus.mib.org) said:

| "dspfun" <ds****@hotmail.comwrites:
|| Morris Dovey wrote:
| [...]
||| It's not unusual to see something like:
|||
||| node *head; /* Pointer to first element */
||| node *tail; /* Pointer to final element */
|||
||| or even:
|||
||| struct
||| { node *head;
||| node *tail;
||| } mylist;
|||
||| to provide a "root" for a list.
||
|| I'm probably missing something here because I don't see what the
|| purpose of such a list would be, all it is is a list of node
|| pointers, isn't it? What is the use of such a list? Wouldn't one
|| like to have some data at each entry of a list?
|
| Yes, absolutely. A linked list with no actual data isn't much use,
| except as a demonstration.
|
| Possibly Morris thought that adding an extra "payload" member would
| distract from the main point.

You can get a glimpse of my tortured thought processes in
http://www.iedu.com/mrd/c/queue.c

I'm inclined to define elements (nodes) like:

typedef struct element_d
{ struct element_d *link;
/* Payload data */
} element;

and then declare a list control structure (without payload):

struct
{ element *head;
element *tail;
} some_list = { NULL,NULL };

because it's not unusual for me to have several lists being
manipulated within the same application. It's generally more
economical to pass a pointer to some_list in one situation; or to pass
a pointer to some_other_list elsewhere so that a set of common list
manipulation functions can massage either list.

--
Morris Dovey
DeSoto Solar
DeSoto, Iowa USA
http://www.iedu.com/DeSoto
Ok, I'm starting to understand it now! :-)

Thank you all for your help, you've been very kind!

The code I was reading is from:

http://www.gentoo.org/doc/en/articles/l-posix3.xml

BR!

Aug 10 '06 #14

Morris Dovey wrote:
Morris Dovey (in 44***********************@news.qwest.net) said:

| dspfun (in 11**********************@75g2000cwc.googlegroups.c om)
| said:
|
|| struct node {
|| void *next;
|| };
|
| Certainly.

Oops! I missed the 'void'. It would _not_ be better.

--
Morris Dovey
DeSoto Solar
DeSoto, Iowa USA
http://www.iedu.com/DeSoto
Is the reason of the void pointer solution not being better that you
can't access the members of the void pointer without doing a cast first
to some specific type?

Aug 10 '06 #15
dspfun (in 11**********************@b28g2000cwb.googlegroups. com)
said:

| Morris Dovey wrote:
|| Morris Dovey (in 44***********************@news.qwest.net) said:
||
||| dspfun (in 11**********************@75g2000cwc.googlegroups.c om)
||| said:
|||
|||| struct node {
|||| void *next;
|||| };
|||
||| Certainly.
||
|| Oops! I missed the 'void'. It would _not_ be better.
|
| Is the reason of the void pointer solution not being better that you
| can't access the members of the void pointer without doing a cast
| first to some specific type?

You're on the right track. I think "better" is providing the compiler
with the information needed to eliminate (or at least minimize) casts.

The biggest benefit, for me, is that this approach allows the compiler
to complain when I do something stupid.

--
Morris Dovey
(Cast-free now for five years, three months, and two days)
Aug 10 '06 #16
"dspfun" <ds****@hotmail.comwrites:
Morris Dovey wrote:
>Morris Dovey (in 44***********************@news.qwest.net) said:
[...]
>--
Morris Dovey
DeSoto Solar
DeSoto, Iowa USA
http://www.iedu.com/DeSoto

Is the reason of the void pointer solution not being better that you
can't access the members of the void pointer without doing a cast first
to some specific type?
Please don't quote signatures unless you're actually commenting on
them. We appreciate the fact that you're providing context in your
followups, but quoting signatures, or anything else that isn't
relevant to your followup, is just clutter.

--
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.
Aug 10 '06 #17

Would you say that this is the best (most processor cycle effective,
least memory consuming and least bug prone) way to implement a linked
list in C?

Aug 10 '06 #18
dspfun (in 11**********************@m79g2000cwm.googlegroups. com)
said:

| Would you say that this is the best (most processor cycle effective,
| least memory consuming and least bug prone) way to implement a
| linked list in C?

Hmm. I have no *this pointer. :-)

Nope. The best way to implement a linked list depends on the problem
you're solving. Lists can be singly- or multiply-linked, they may
optimized for FIFO or LIFO (or other) access, and they may be
unordered or ordered in about any way imaginable.

_You_ get to decide what works best.

[ Reminds me of a movie in which the last words said of one of the
characters was "He chose unwisely." ]

--
Morris Dovey
DeSoto Solar
DeSoto, Iowa USA
http://www.iedu.com/DeSoto
Aug 10 '06 #19
"dspfun" <ds****@hotmail.comwrites:
Would you say that this is the best (most processor cycle effective,
least memory consuming and least bug prone) way to implement a linked
list in C?
What is? Please provide enough context so we can understand what
you're talking about without seeing the parent article.

--
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.
Aug 10 '06 #20

Keith Thompson wrote:
"dspfun" <ds****@hotmail.comwrites:
Would you say that this is the best (most processor cycle effective,
least memory consuming and least bug prone) way to implement a linked
list in C?

What is? Please provide enough context so we can understand what
you're talking about without seeing the parent article.
Sorry, /this/ points to the following (beginning of a) linked list:

typedef struct node {
struct node *next;
/*payload data goes here.*/
} node;

typedef struct queue {
node *head, *tail;
} queue;

Aug 11 '06 #21

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

Similar topics

2
by: Kaptain524 | last post by:
Hello, I am using PHP 5.0.4 with Apache 2, on WinXP Pro. This behavior appears to be fundamental however, and should not be affected by platform. It would seem that there is some kind of bug...
7
by: aurora | last post by:
I love generator and I use it a lot. Lately I've been writing some recursive generator to traverse tree structures. After taking closer look I have some concern on its performance. Let's take...
7
by: Jon Slaughter | last post by:
#pragma once #include <vector> class empty_class { }; template <int _I, int _J, class _element, class _property> class RDES_T {
25
by: Mike MacSween | last post by:
Regular viewers may want to turn off now. This will be an orchestral management system. Musicians and other staff being booked/paid for jobs. A job may contain other jobs, e.g: World Tour...
5
by: brett valjalo | last post by:
Hey Gang! SORRY ABOUT THE LENGTH! Nice to see some of the same faces around this place from way back when ... Whatta buncha CDMA addicts some o' y'all are ;) Don't get me wrong, I...
9
by: Paul | last post by:
I'm trying to make get my app to delete all the files in a specified folder and all the files within the folders of the specified folder. e.g. Folder 1 contains three files (File1, File2, File3)...
1
by: ozcanseker | last post by:
I am trying to write a product-row material cost program. Every product consists of row materials. When I sum up cost of row materials of each product I can find cost of products. But when the row...
4
by: so.intech | last post by:
for example, ret = 0; for(i=0; i<3; i ++;) { for(j=0; j<4; j++;) { for(k=0; k<3; k++;) { for(m=0; m<4; m++;) {
3
by: mizrandir | last post by:
Can someone tell me why python doesn't crash when I do the following: ] ] How does python handle this internally? Will it crash or use up lot's of memory in similar but more complicated cases?
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
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
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
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.