New with nodes in C, how to fix the struct? - c

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;
}

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();
}

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);
}

You are calling list_create, but not using its result.

Related

creating a list of nodes with C

I want to createe a list of nodes that links to each other, I use head to remember the address of the first node, prev to link, and newdata to get the input, but it turns out that my head prev and newdata are all in the same address, can someone help me with this plz
typedef struct node
{
void* stdPtr;
struct node* link;
}NODE;
NODE* createNode(void* std)
{
NODE* nodePtr;
nodePtr=(NODE*)malloc(sizeof(NODE));
nodePtr->stdPtr=std;
nodePtr->link=NULL;
return nodePtr;
}
typedef NODE* nodePtr;
int main(void)
{
FILE* fin;
fin=fopen("input.txt","r");
//define
int i=0;
intPtr ID,grade;
STD* stdinfo;
nodePtr head=NULL;
nodePtr prev=(nodePtr)malloc(sizeof(NODE));
//nodePtr newdata=(nodePtr)malloc(sizeof(NODE));
prev=head;
//malloc space to ptr
ID=(intPtr)malloc(sizeof(int));
grade=(intPtr)malloc(sizeof(int));
stdinfo=(STD*)malloc(sizeof(STD));
//read student data and compare
while(fscanf(fin,"%d%d",&(stdinfo->ID),&(stdinfo->grade))!=EOF)
{
nodePtr newdata=(nodePtr)malloc(sizeof(NODE));
newdata=createNode(stdinfo);
if (prev==NULL)
{
prev=newdata;
head=prev;//為什麼只有在這裡=prev後面會跑掉?
}
printf("%d %d\n",*(int*)head,*(int*)prev);
if(prev->link!=NULL)
{
prev=prev->link;
}
prev->link=newdata;
}
fclose(fin);
return 0;
}
Important parts are missing (types, input.txt) to run your program which makes it harder to help you.
You create an instance of STD prior to the loop, then overwrite whatever data you store in it on each iteration and store the address of that one instance in each node. You need to create an instance of both NODE and STD per loop iteration (or change the definition of NODE so it can hold the STD data instead of a pointer to STD).
You use this pattern a couple of times which allocate data, then immediately leak the data by overwriting the pointer:
nodePtr prev=(nodePtr)malloc(sizeof(NODE));
prev=head;
...
nodePtr newdata=(nodePtr)malloc(sizeof(NODE));
newdata=createNode(stdinfo);
Here is more straight forward version to get you going:
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
void *stdPtr;
struct node* link;
} NODE;
NODE* createNode(void *std, NODE *prev) {
NODE *nodePtr = malloc(sizeof(NODE));
nodePtr->stdPtr=std;
nodePtr->link=prev;
return nodePtr;
}
void printNodes(NODE *tail) {
for(; tail; tail = tail->link) {
printf("%s\n", (const char *) tail->stdPtr);
}
}
int main(void) {
NODE *tail = NULL;
tail = createNode("hello", tail);
tail = createNode("world", tail);
printNodes(tail);
}

recursively call in c to create link list

I am new in c so any help will be appreciated. I need to print 10 numbers from a linked list (it doesnt matter which numbers for now) I believe my code will print 9,8,7...0. for example. The linked list will be part of a struct (struct data) that will contain other variables (not important for now)
//linked list
struct listOfNodes {
struct node *root;
};
//list of parameters to send to the function to print nodes
struct data {
struct listOfNodes *list;
int total;
};
I need to send the struct (struct data) as a parameter of a recursive function (addNode). In this recursive function, I need to add a new node to the linked list and call recursively 10 times to create more nodes for the link list, then I need to print the linked list. I have the following code so far
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//node
struct node {
int value;
struct node *next;
};
//linked list
struct listOfNodes {
struct node *root;
};
//list of parameters to send to the function to print nodes
struct data {
struct listOfNodes *list;
int total;
};
void printNode(struct listOfNodes *list) {
struct node *n = list->root;
while(n!=NULL){
printf("%d\n",n->value);
n=n->next;
}
}
void addNode(void* d){ //parameter needs to be a void*
struct data *o = (struct data *)d ;
if(o->total<10) {
//create new node
struct node *n = malloc(sizeof(struct node));
n->value = o->total;
n->next = NULL;
o->total = o->total + 1;
if(o->list->root == NULL)
{
o->list->root = n;
}
else {
n->next = o->list->root->next;
o->list->root->next = n;
}
addNode(d);
}
}
int main() {
struct data *d= malloc(sizeof(struct data *));
d->total=0;
d->list=NULL;
addNode(d); //add recursively 10 times
if(d->list!=NULL) printNode(d->list);
return 0;
}
But I am getting Segmentation fault (core dumped). Can you please help me?
In your main program, you added list as NULL. But in your addNode, you only check if list->root is NULL. What's happening is when
if(o->list->root == NULL)
{
o->list->root = n;
}
is accessing list->root when list is NULL. You de reference a NULL pointer and segfault.
You probably need
struct listOfNodes *variable=malloc(sizeof(struct listOfNodes));
d->list=variable;
Changes are describe in comments
#include <stdio.h>
// #include <string.h> // <------- 4 not needed.
#include <stdlib.h>
struct node {//node
int value;
struct node *next;
};
struct listOfNodes {//linked list
struct node *root;
};
struct data {//list of parameters to send to the function to print nodes
struct listOfNodes *list;
int total;
};
void printNode(struct listOfNodes *list) {
struct node *n = list->root;
while(n!=NULL){
printf("%d\n",n->value);
n=n->next;
}
}
void addNode(struct data * d){ // <------- 3 no need to be void * so o replaced by d
if(d->total<10) {
//create new node
struct node *n = malloc(sizeof(struct node));
n->value = d->total;
n->next = NULL;
d->total = d->total + 1;
if(d->list->root == NULL)
{
d->list->root = n;
}
else {
n->next = d->list->root->next;
d->list->root->next = n;
}
addNode(d);
}
}
int main() {
struct data *d= malloc(sizeof(struct data)); // <---- 1 allocate data size not pointer size.
d->total=0;
d->list = malloc(sizeof(struct listOfNodes)); // <---- 2 alocate list !
d->list->root = NULL; // <---- 2 init root.
addNode(d); //add recursively 10 times
if(d->list!=NULL) printNode(d->list);
return 0;
}

Node in linked-List with C language

I start learning linked list,so my question may be stupid :p . I noticed that in all the exercices, they only take one data element in the node( as below : int data).So i am asking can we define multiple data elements in one node.Otherwise why not?
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node* nextptr;
};
struct node* BuildList()
{
/* initialize node's pointers */
struct node* head = NULL;
struct node* second = NULL;
struct node* third = NULL;
/* allocate three nodes in the heap*/
head = malloc(sizeof(struct node));
second = malloc(sizeof(struct node));
third = malloc(sizeof(struct node));
/* setup first node */
head->data = 1;
head->nextptr = second;
second->data = 2;
second->nextptr = third;
third->data =3;
third->nextptr = NULL;
return head;
}
Yes, int just make it easier for the examples. But in real life, the node will be something more useful. Example:
struct chair {
int nr_or_legs;
int weight_in_kg;
int height_in_cm;
};
struct chair_node {
struct chair data;
struct chair_node* nextptr;
};
or just:
struct chair_node {
int nr_or_legs;
int weight_in_kg;
int height_in_cm;
struct chair_node* nextptr;
};

I can not pass by reference my node

I dont want create general *head node and I want to pass by reference and chance my data but although create new node for next node I cant reach my new node on main.
İf I look n1.next in main I see it is null.Why ?What is wrong ?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct node{
int data;
struct node* next;
};
void add(struct node** head,int data){
struct node * tmp = *head;
while(tmp != NULL){
tmp = tmp->next;
}
tmp = (struct node*) malloc(sizeof(struct node));
tmp->data= data;
tmp->next=NULL;
}
int main()
{
struct node n1;
n1.data=5;
n1.next=NULL;
add(&(n1.next),15);
printf("%d",n1.next->data);
return 0;
}
Instead of using a head pointer, are you trying to pass in the last next pointer in the list, and then update that to point to your new node? If so, add() should be
void add(struct node** head, int data) {
struct node* p = malloc(sizeof(*p));
p->data = data;
p->next = NULL;
*head = p;
}

can't use a function with a 'pointer to pointer' input in another function. In C language

this code supposed to print : 'tree two one'
but it doesn't work. (the new_nod isn't added to the front of mylist)
anybody knows why? (actually in this code i wanted to use a function with a pointer to pointer input in another function but it didn't work(no changes applied to the mylist).
but it works when i'm using add_front function straightly in main.
#include <stdio.h>
#include <stdlib.h>
struct node{
char *word;
struct node *next;
};
struct node* create_node(char *str){
struct node *s;
s = (struct node *)malloc(sizeof(struct node));
if(s==NULL){
printf("couldn't malloc :(\n");
exit(-1);
}
s->word = str;
s->next = NULL;
return s;
}
void print_node(struct node *list){
struct node *current;
for(current = list; current !=NULL; current = current->next)
printf("%s ", current->word);
}
void add_front(struct node **list, struct node *new_node){
new_node->next= *list;
*list = new_node;}
void func(struct node*list, struct node*new_node){
add_front(&list, new_node);
}
int main()
{
struct node* mylist = create_node("one");
mylist->next = create_node("two");
struct node *new_node = create_node("tree");
func(mylist, new_node);
print_node(mylist);
}
Your add_front accepts a pointer to a pointer and other than missing a check for NULL is pretty much okay. But let's take a look at this:
void func(struct node*list, struct node*new_node){
add_front(&list, new_node);
}
What is add_front modifying here? The local pointer list. Which is just a copy of mylist in main.
So you haven't changed what mylist is pointing to.

Resources