1

I have problems with understanding the whole concept of this. The major issue that confuses me is the the pointer inside a struct inside a struct... Basically what I understand is that I am wanting to create a chain of nodes.

When I run this program it crashes after two seconds. I believe there is something wrong with my structure in main.c, because I have created it by myself and as you can see I am really Bambi on thin ice over here...

main.c

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

#include "list.h"

// I guess my struct is not correct
static struct {
    LIST node;
    int item;
} node;


int main() {

    list_create();

    list_append(node.node, node.item);
}

list.h

typedef struct node* LIST;

LIST  list_create   (void);
void  list_append   (LIST l, int item);

list.c

struct node* list_create() {

 struct node* head = (struct node*) malloc(sizeof (struct node));
 head->next = NULL;
 return head;

}

void list_append(struct node* n, int item)
{

    /* Create new node */
    struct node* new_node = (struct node*) malloc (sizeof (struct node));
    new_node->item = item;


    /* Find last link */
    while (n->next) {
        n = n->next;
    }

    /* Joint the new node */
    new_node->next = NULL;
    n->next = new_node;
}

3 Answers3

1

At first, node is use for create a structure with data and in THIS data you have a pointer to another struct.

static struct {
    LIST node;
    int item;
} node;

Actually your structure is incorrect.

You must create at beginning a structure with your data for example :

static struct node{
    int item;
};

then put a pointer to the similar structure but will not have same data =>

static struct node{
    struct node *next;
    int item;
};

You will can use this pointer to manipulate other & other structure.

I see another problem in your main :

You call the function "list_create()" which return a pointer to structure but you assign nothing.

you must create a pointer to struct then assign it like this :

int main() {

struct node *list;
    list = list_create();
}
Laykker
  • 322
  • 1
  • 3
  • 12
  • Ok, I do not fully understand this but why are you not assigning a name to the struct? I mean shouldn't the name of the struct be between those characters `};`, like this `} node;` so that I can type `node.item`? – user3241763 Jan 28 '14 at 20:14
  • there is different way to name a struct, first is: struct name {}; but you can us "typedef". – Laykker Jan 28 '14 at 20:21
  • I have seen people making a struct like this `struct node {} head = {0, NULL };`. In my eyes they first create a struct called `node`. Then they rename it to `head`?! :( – user3241763 Jan 28 '14 at 20:24
  • There is typedef for recall struct like `typedef struct s_node{} node; `. Then when you create a struct you can do `struct s_node` or `node`. – Laykker Jan 28 '14 at 21:24
1

This code works completely (you can put it all in one C file; annotations in the code):

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

/* I removed the "static", because what we want is a type, 
   not a global static variable */
/* This "node" is our list-element. It has a pointer to a next element, and
   some data, in this case, an int. */
typedef struct node {
    struct node *next;
    int item;
} node;

/* For convenience, another type, a pointer to a node. */
typedef  node *LIST;


/* Creating a list is as simple as creating a node, and make the "next"
   pointer NULL, you got this correct. */
struct node* list_create() {
   struct node* head = (struct node*) malloc(sizeof (struct node));
   head->next = NULL;
   return head;
}

/* Nothing wrong in this append code. */
void list_append(struct node* n, int item)
{
    /* Create new node */
    struct node* new_node = (struct node*) malloc (sizeof (struct node));
    new_node->item = item;


    /* Find last link */
    while (n->next) {
        n = n->next;
    }

    /* Joint the new node */
    new_node->next = NULL;
    n->next = new_node;
}

/* I added this to make sure it works :) */    
void print_list(LIST l) {
        LIST tmp = l;
        while (tmp) {
                printf("%d\n", tmp->item);
                tmp = tmp->next;
        }

/* Here are some changes. I create a local LIST (which is basically a pointer
   to a node, remember?) and use list_create to initialise it. Then, I call
   list_append two times to put some extra data into it.
   Works perfectly! */
int main() {
    LIST myList = list_create();
    list_append(myList, 10);
    list_append(myList, 13);

    print_list(myList);
}
Bart Friederichs
  • 33,050
  • 15
  • 95
  • 195
  • Ooh, things are getting a bit clearer but I can not understand how the pointer in the struct that is inside another struct works. I guess that pointer has some information about the next node, no...? Also I have no idea what `typedef struct node* LIST;` does. I can't understand it... – user3241763 Jan 28 '14 at 20:22
  • "It just works.". It is probably possible because a pointer is always the same, the compiler doesn't really need the **exact** type to a pointer to be able to declare it. It is just a memory address, after all. – Bart Friederichs Jan 28 '14 at 20:28
  • `typedef struct node *LIST` is three pieces: `typedef` tells the compiler you are defining a new type. `struct node *` is the type you are defining a new new for and finally `LIST` is the name of the typedef. It is all convenience stuff though, you can replace `LIST` with `struct node *` and the code runs exactly the same. – Bart Friederichs Jan 28 '14 at 20:29
  • This explains a little extra: http://stackoverflow.com/questions/3988041/struct-containing-pointers-to-itself – Bart Friederichs Jan 28 '14 at 20:40
0

You are calling list_create, but not using its result.

Mark Borgerding
  • 8,117
  • 4
  • 30
  • 51