Here's my code:
#include <stdio.h>
typedef struct node_struct {
int data;
struct node_struct *next;
} node;
void push(node *top, int data) {
node *new_node = (node*) malloc(sizeof(node));
new_node->data = data;
new_node->next = top;
top = new_node;
}
int main() {
node *top = (node*) malloc(sizeof(node));
top->data = 1;
printf("Set data of top node to: %d\n", top->data);
push(top, 2);
printf("Pushed 2 to top, top->next->data = %d\n", top->next->data);
}
The program segfaults at the 3rd last line (push(top, 2);) and I think on the line top = new_node;
I'm just learning C (pointers right now).
What did I do wrong?
The problem here is that you pass the pointer to the top element by-value, and then you try to set the pointer inside the function but there it's just a local variable and changes to it will not be visible outside of the function.
Pass the top pointer by reference instead, by using a pointer to the pointer:
void push(node **top, int data) {
node *new_node = malloc(sizeof(node));
new_node->data = data;
new_node->next = *top;
*top = new_node;
}
...
push(&top, 2);
An alternative is to return the new top from the function instead:
node *push(node *top, int data) {
node *new_node = malloc(sizeof(node));
new_node->data = data;
new_node->next = top;
return new_node;
}
...
top = push(top, 2);
Pointer is passed by value to push. Hence, the change you did to top is not reflected in main. If you want to change top then pass the address of pointer:
#include <stdio.h>
typedef struct node_struct {
int data;
struct node_struct *next;
} node;
void push(node **top, int data) {
node *new_node = (node*) malloc(sizeof(node));
new_node->data = data;
new_node->next = *top;
*top = new_node;
}
int main() {
node *top = (node*) malloc(sizeof(node));
top->data = 1;
printf("Set data of top node to: %d\n", top->data);
push(&top, 2);
printf("Pushed 2 to top, top->next->data = %d\n", top->next->data);
}
Here's the relevant C-FAQ.
Related
I am trying to add strings to a linked list but I have a problem with (null) being printed. Anyone who can help me?
The best I could do is narrow it down to this being the problem:
struct node *head = malloc(sizeof(struct node));
struct node *ptr = malloc(sizeof(struct node));
Here is the code:
#include <stdio.h>
#include <stdlib.h>
struct node {
char *data;
struct node *link;
};
struct node *add_begin(char *d, struct node *head) {
struct node *ptr = malloc(sizeof(struct node));
ptr->data = d;
ptr->link = head;
return ptr;
}
void add_end(struct node *point, char *data) {
struct node *temp = malloc(sizeof(struct node));
temp->data = data;
temp->link = NULL;
while (point->link != NULL) {
point = point->link;
}
point->link = temp;
}
int main() {
struct node *head = malloc(sizeof(struct node));
struct node *ptr = malloc(sizeof(struct node));
head->link = ptr;
char *data = "Chocolate Cake";
head = add_begin(data, head);
add_end(ptr, data);
while (head != NULL) {
printf("%s \n", head->data);
head = head->link;
}
}
Output:
Chocolate Cake
(null)
(null)
Chocolate Cake
The problem is you allocate dummy nodes, which are uninitialized and happen to have null pointers as data and link. The list should be initially empty, ie: head should be a null pointer.
Note that add_end should also return the head pointer in case an empty list was passed. Passing the arguments in the same order to both functions is highly recommended.
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
struct node {
char *data;
struct node *link;
};
struct node *add_begin(struct node *head, char *data) {
struct node *ptr = malloc(sizeof(*ptr));
ptr->data = data;
ptr->link = head;
return ptr;
}
struct node *add_end(struct node *head, char *data) {
struct node *ptr = malloc(sizeof(*ptr));
ptr->data = data;
ptr->link = NULL;
if (head == NULL) {
return ptr;
} else {
struct node *temp = head;
while (temp->link != NULL) {
temp = temp->link;
}
temp->link = ptr;
return head;
}
}
int main() {
struct node *head = NULL;
char *data = "Chocolate Cake";
head = add_begin(head, data);
head = add_end(head, data);
for (struct node *ptr = head; ptr; ptr = ptr->link) {
printf("%s\n", ptr->data);
}
return 0;
}
Output:
Chocolate Cake
Chocolate Cake
I'm trying to store an array of pointers to a node. In the createlist() function, I have initialized the array of pointers with
linked_list_array[i] = createNode(-1); for each item in the array.
Then I assigned it to list->linkedLists with list->linkedLists = linked_list_array.
It seems that once I return list back into the main function, the value of list->linkedLists[0]->key changed.
Why is it that the value changed?
#include <stdio.h>
#include <stdlib.h>
#define NEG_INF (-32727)
struct leapList{
int maxHeight;
int curr_height;
struct Node **linkedLists;
double prob;
};
struct Node{
struct Node* next;
struct Node* below;
int key;
};
struct Node* createNode(int key){
struct Node* new_node = (struct Node*)malloc(sizeof(struct Node));
new_node->next = NULL;
new_node->below = NULL;
new_node->key = key;
return new_node;
}
struct leapList* createList(int maxheight, double p){
struct leapList* list = (struct leapList*)malloc(sizeof(struct leapList));
list->maxHeight = maxheight;
list->prob = p;
list->curr_height = 0;
struct Node* linked_list_array[maxheight];
for(int i=0;i<maxheight;i++){
linked_list_array[i] = createNode(-1);
}
list->linkedLists = (linked_list_array);
printf("key inside function: %d\n", list->linkedLists[0]->key);
return list;
}
struct Node* insertNode(struct Node** headref, int key){
struct Node* curr_node = NULL;
struct Node* new_node = createNode(key);
if(*headref == NULL || (*headref)->key >= key){
new_node->next = *headref;
*headref = new_node;
}else{
curr_node = *headref;
while(curr_node->next!=NULL && curr_node->next->key < key){
curr_node = curr_node->next;
}
new_node->next = curr_node->next;
curr_node->next = new_node;
}
//printf("%d ", new_node->key);
return new_node;
}
int main(int argc, const char * argv[]) {
// insert code here...
struct leapList* list = createList(5, 0.5);
printf("key outside function: %d", list->linkedLists[0]->key);
struct Node* head_node = createNode(-37273);
insertNode(&head_node, 5);
insertNode(&head_node, 3);
insertNode(&head_node, 1);
return 0;
}
This is what I get after running the program
You set list->linkedLists to point to a local ("automatic storage") variable.
...
struct Node* linked_list_array[maxheight];
...
list->linkedLists = linked_list_array;
...
It's no longer legal to access linked_list_array after the function returns, yet that's what you end up doing. This is Undefined Behaviour.
You will need to malloc the array.
here's part of my code for the linked list:
struct node {
float data;
int key;
struct node* next;
};
typedef struct{
struct node *head;
struct node *current;
int length;
} linked_list;
linked_list *init_list(){
linked_list *out = malloc(sizeof(linked_list));
struct node *head = NULL;
struct node *current = NULL;
out->head = head;
out->current = current;
out->length = 0;
return out;
}
void push_core(struct node *head, int key, float data){
struct node *link = malloc(sizeof(struct node));
link->data = data;
link->key = key;
link->next = head;
// readjust to point at the new first node
head = link;
printf("%f; ", head->data);
}
void push(linked_list *list, int key, float data){
push_core(list->head, key, data);
list->length ++;
}
void print_list_core(struct node *head){
struct node* ptr = head;
printf("\n[");
while(ptr != NULL){
printf("(%d,%f)", ptr->key, ptr->data);
ptr = ptr->next;
}
}
void print_list(linked_list *list){
print_list_core(list->head);
}
But in the main, after I initialized the linked list structure, I wasn't able to use push() to link new pointers, why is that?
linked_list *S = init_list();
for (int i = 0; i < n; i++)
{
push(S,i,0);
print_list(S);
printf("%d;", S->length);
}
To clarify, the length of the list does update correctly. But when I try to print the list it doesn't work. Also, it's interesting that in another file when I initially just worked with the node struct and defined global variables for head and current, the code works fine. But when I try to wrap them up inside this linked_list struct, things aren't quite working as expected.
The problem occurred because you passed the pointer value of list->head to your push_code function as a parameter. This is a function call-by-value. So, when you change the head pointer inside the push_core function, it actually do not change the list->head pointer that you are expecting to. One quick fix would be returning the newly created link pointer from the push_core function and save it as list->head. The following code should fix your problem.
struct node * push_core(struct node *head, int key, float data){
struct node *link = malloc(sizeof(struct node));
link->data = data;
link->key = key;
link->next = head;
return link;
}
void push(linked_list *list, int key, float data){
list->head = push_core(list->head, key, data);
list->length ++;
}
could someone to help me to solve this problem
I have several line code but I got stuck in fuction display where I want to return elems, how I can fix it..I need function and return is as feedback not printf
#include <limits.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "IO.c"
struct node{
int data;
struct node* next;
};
void append(struct node** head_ref, int data)
{
struct node* new_node = (struct node*) malloc(sizeof(struct node));
struct node *current = *head_ref;
new_node->data = data;
new_node->next = NULL;
if (*head_ref == NULL)
{
*head_ref = new_node;
return;
}
while (current->next != NULL)
current = current->next;
current->next = new_node;
return;}
int display(struct node *head){
struct node* elems = NULL;
struct node* current = head;
while (current != NULL)
{
current = current->next;
append(&elems,current->data);
}
return elems;
}
int main(){
read_2array_data_file("datauji.dat");
struct node* tetangga = NULL;
append(&tetangga, 1);
append(&tetangga, 2);
append(&tetangga, 3);
append(&tetangga, 3);
display(tetangga);
}
display() needs to be declared to return struct node* so it can return elems. And then you should assign the result to a variable in main().
When you're copying the list in display, you need to update current after you reference current->data.
struct node *display(struct node *head){
struct node* elems = NULL;
struct node* current = head;
while (current != NULL)
{
append(&elems,current->data);
current = current->next;
}
return elems;
}
int main(){
read_2array_data_file("datauji.dat");
struct node* tetangga = NULL;
append(&tetangga, 1);
append(&tetangga, 2);
append(&tetangga, 3);
append(&tetangga, 3);
struct node *elements = display(tetangga);
}
I have implemented a simple linked list in C language, but can it be implemented without using double-pointer(**).I want to implement same program by using only single pointers.
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *next;
};
void push(struct node** head_ref, int new_data)
{
struct node* new_node = (struct node*) malloc(sizeof(struct node));
new_node->data = new_data;
new_node->next = (*head_ref);
(*head_ref) = new_node;
}
void append(struct node** head_ref, int new_data)
{
struct node* new_node = (struct node*) malloc(sizeof(struct node));
struct node *last = *head_ref; /* used in step 5*/
new_node->data = new_data;
new_node->next = NULL;
if (*head_ref == NULL)
{
*head_ref = new_node;
return;
}
while (last->next != NULL)
last = last->next;
last->next = new_node;
return;
}
void printList(struct node *node)
{
while (node != NULL)
{
printf(" %d ", node->data);
node = node->next;
}
}
int main()
{
struct node* head = NULL;
append(&head, 6);
push(&head, 7);
push(&head, 1);
append(&head, 4);
printf("\n Created Linked list is: ");
printList(head);
getchar();
return 0;
}
Is it possible to replace "struct node** head_ref" with "struct node* head_ref"?
Changed code after suggestions(still not getting output)
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *next;
};
struct node* push(struct node* head, int new_data)
{
struct node* new_node = (struct node*) malloc(sizeof(struct node));
new_node->data = new_data;
new_node->next = head;
head = new_node;
return head;
}
struct node* append(struct node* head, int new_data)
{
struct node* new_node = (struct node*) malloc(sizeof(struct node));
struct node *last = head; /* used in step 5*/
new_node->data = new_data;
new_node->next = NULL;
if (head == NULL)
{
head = new_node;
return head;
}
while (last->next != NULL)
last = last->next;
last->next = new_node;
return head;
}
void printList(struct node *node)
{
while (node != NULL)
{
printf(" %d ", node->data);
node = node->next;
}
}
int main()
{
struct node* head = NULL;
head= append(&head, 6);
head=push(&head, 7);
head=push(&head, 1);
head=append(&head, 4);
printf("\n Created Linked list is: ");
printList(head);
getchar();
return 0;
}
Yes, you can rewrite this code using only single pointers, but you would have to change the semantic of your API and the pattern in which it is used.
Essentially, you replace the second level of indirection in
void push(struct node** head_ref, int new_data)
with a client-side assignment, i.e.
struct node* push(struct node* head, int new_data)
This means that instead of
push(&head, num);
the caller will have to write
head = push(head, num);
Same goes for the implementation of append.
Replace (&head,6) with (head,6).As you are not passing the address of the head, on receiving end you have push(struct node* head, int new_data).Rest all have been clarified by above given answer
Another solution is to create an empty node called head, and then create a pointer to that node called list. You can then pass list to all of the functions, like this
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *next;
};
void push(struct node *list, int new_data)
{
struct node* new_node = malloc(sizeof(struct node));
new_node->data = new_data;
new_node->next = list->next;
list->next = new_node;
}
void append(struct node *list, int new_data)
{
while ( list->next != NULL )
list = list->next;
push( list, new_data );
}
void printList(struct node *node)
{
for ( node=node->next; node != NULL; node=node->next )
printf(" %d ", node->data);
printf( "\n" );
}
int main( void )
{
struct node head = { 0, NULL };
struct node *list = &head;
append(list, 6);
push(list, 7);
push(list, 1);
append(list, 4);
printf("\n Created Linked list is: ");
printList(list);
getchar();
return 0;
}