Sorry for asking a basic question, I am learning C and I got confused with assigning a value for a list. I got confused with my own question that pops into my head.. :(
So for instance, I have a struct below
typedef struct {
int value_in_use;
} structA;
typedef struct structB {
structA conn;
struct structB *next, *prev;
} structB
typedef struct {
structB *head, *tail;
} structC;
and I want to assign the value of "value_in_use" equal 1. I am totally confu开发者_StackOverflowsed, as what I understand, that in a list, I need to traverse from the head first(StructC), and I need to go inside the list until I get into structA and assign value to it. So something like
structC *C = NULL;
C = (structC *) malloc(sizeof(structC));
int assign=1;
&C->structB.head->conn.value_in_use=assign;
Meanwhile, I was thinking that I can actually assign a pointer to structA directly and assign value to it. So I can just say
structA *ue = NULL;
ue = (structA *) malloc(sizeof(structA));
ue->value_in_use = 100;
How does it differ for assigning the value of a list in run time in the first part and second part? I believe I can use both for assigning value (or?) ..
Thank you so much for sharing your knowledge with me.
The first one in fact won't actually work. You're trying to follow a head pointer from C, but you have no idea where that pointer points to (i.e. malloc is not recursive).
For the first case, you would need to do something like this:
structC * c = malloc(sizeof(structC));
structB * b = malloc(sizeof(structB));
c->head = b;
c->tail = b;
b->next = NULL;
b->prev = NULL;
c->head->conn.value_in_use = 1;
Note that we do not have to allocate a structA separately, since there is one embedded in B.
You will have to first allocate memory for structC
then you have to allocate memory to the pointers inside it (*head
, *tail
) and then you can assign value to conn
.
So here is the detail on the 3 step procedure with explanation:
Step 1:
structC *C = NULL;
C = (structC *) malloc(sizeof(structC));
C
is just a pointer to type struct C
now, that means it just points to a memory of size of a pointer type somewhere on the stack. By using malloc
what you are doing is allocating(reserving) a space of size struct C
for it.
Step 2:
C->head= (structA *) malloc(sizeof(structA));
Now the pointer head
inside the structure C(structC)
again just points to a memory of size of an pointer, You need to allocate it a size of(structA
) by using the malloc statement above.
Step 3:
Once C->head
points to a memory big enough to hold a strct A
you can now assign value of your choice to it.
C->head->value_in_use = 100;
I'm not really sure where to begin on this one. Note that structA
, structB
, and structC
seem to represent different 'levels', so to speak, of your doubly-linked list implementation. structA
represents the actual data or list members, structB
represents a data member and its connections, and structC
represents the entire list itself. Note also that structC
only contains pointers to values in the list. By allocating a structC
as in your first code example, it will not contain any useful information or allocate space for members. You should immediately clear the memory because the pointers will not be valid. Thus, your first code example won't work. I would expect you would do something like (warning: untested code)
structC* c = malloc(sizeof(structC)); // note: don't cast the pointer from malloc in C
structB* b = malloc(sizeof(structB)); // you now have a data member
memset(b, 0, sizeof(structB));
c->head = b;
c->tail = b;
b->conn.value_in_use = 1;
Now you have a list with one member in use.
You write to random memory in your second example, the adress-of operator (&
) is the culprit (I'm surprised that error haven't been caught by the C-compiler).
In your third example, you just allocate memory for a structA
, pointed to by ua
that is not linked to anything resembling a tree structure. As you have implemented structB
, memory for conn
is part of the record, if memory for a structB
is allocated dynamically with malloc
, then you get conn
for free as part of the allocated memory. If a structB
is created in static memory or on the stack as a "normal" (from the point of view of languages that don't use pointers or dynamic memory allocation) variable, then the record conn
share that same memory.
I hope I didn't add to the confusion (sorry about my lacking English skills)
I can give you some good advice:
First: I recommend that you use more descriptive names as a start. Why not root
, node
and data
for the structures.
Second: I recommend reading a good beginners book about C. The C Programming language by Kernighan & Ritchie is a classic, but don't deal much with pointers, it is reasonably easy to read for someone without any prior exposure to other programming languages, but not really a book to begin programming with. Pointers on C by Kenneth Reek concentrate on parts of C that is different from other programming languages, mainly pointers and the C memory model. Pointers on C also provide good implementations of basic data structures, like trees. As far as I know, there aren't any good articles on Internet for aspiring C programmers.
Third: Read a good book or web-page about data structures and the algorithms to use with them. I have seen some good web-pages about the subject, but I'm not able to find them now.
精彩评论