How to implement a [copy array to linked list] function? - c

What this supposed to do is:
Create an array with 4 elements.
Print these 4 elements.
Copy array elements to a created linked list in copy fucntion.
Print linked list with print and traverse fuction.
I tried this and it compiles, but crashes after printing the array.
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#define ELEMENTS 4
struct node {
int data;
struct node *next;
};
struct node *head;
void insert(int x) {
struct node *temp = malloc(sizeof(struct node));
temp->data = x;
temp->next = NULL;
if (head != NULL)
temp->next = head;
head = temp;
}
void copy(struct node *head, int array[ELEMENTS], int n) {
//copying array elements and create linked list
struct node *temp = malloc(sizeof(struct node));
temp->data = array[0];
temp->next = NULL;
head = temp;
int i;
for (i = 1; i < n; i++) {
struct node *temp2 = malloc(sizeof(struct node));
temp->next = temp2;
temp2->data = array[i];
temp2->next = NULL;
temp = temp2;
}
}
void printlist() {
struct node*temp = head;
printf("List is : ");
while (temp->next != NULL) {
printf(" %d ", temp->data);
temp = temp->next;
}
printf("\n");
}
int main() {
int *array = (int*)calloc(ELEMENTS , sizeof(int));
int i = 0;
for (i = 0; i < ELEMENTS; i++) {
printf("arrays = [%d] ", i);
scanf("%d", &array[i]);
}
for (i = 0; i < ELEMENTS; i++)
printf("array [%d] = %d \n", i, array[i]);
copy(head, array[ELEMENTS], ELEMENTS);
printlist();
getchar();
return(0);
}
How to fix it?

You dont need to pass head to the copy function because it is global and when you do you create a local pointer named head which gets destroyed as soon as function is over.
So copy should look like this
void copy(int array[ELEMENTS],int n) //copying array elements and create linked list
{
struct node*temp = malloc(sizeof(struct node));
temp->data=array[0];
temp->next=NULL;
head =temp;
int i;
for(i=1;i<n;i++)
{
struct node*temp2= malloc(sizeof(struct node));
temp->next= temp2;
temp2->data = array[i];
temp2->next = NULL;
temp=temp2;
}
}
Also while printing change while to
while(temp!=NULL)
{
printf(" %d ",temp->data);
temp=temp->next;
}

When you call the function copy, you are passing "array[ELEMENTS]" as an argument, but you want to pass only "array". What you're passing is value after your array, which the copy function is trying to interpret as an address of an array it's actaully expecting.
Note that accessing a value that is not yours like this results in undefined behaviour and can actually make the system kill your application. But what probably happened after is there will be a 0 in the memory, which gets passed to the copy function and it then tries to access values at memory 0x0 to 0xF, which almost always results in segmentation fault, which as you experienced first hand, causes the program to stop working.
Bottom line, delete [ELEMENTS] at the line where you call the copy function and I believe the program should start working. I implore you though to do further research on pointers and passing them as function parameters.
(And since I cannot comment yet I will just put this in here, as Sniper stated, you don't have to pass reference to global variable, but he is wrong about the structure being destroyed at the end of the function. That would have been true, if it was created at stack, but you are allocating space for it at heap, which means it will stay there until you either free() it or the program ends.)

I have simple dimple answer:
#include<stdio.h>
#include<stdlib.h>
struct Node{
int current;
struct Node *next;
};
struct LinkedList{
struct Node *head;
};
int main(){
int i, data[5] = {10, 20, 30, 40, 50};
struct Node *node = malloc(sizeof(struct Node));
struct LinkedList *llist = malloc(sizeof(struct LinkedList));
node->current = data[0];
node->next = NULL;
llist-> head = node;
for(i = 1; i <= sizeof(data) / sizeof(data[0]) - 1; i++){
struct Node *new_node = malloc(sizeof(struct Node));
node->next = new_node;
new_node->current = data[i];
new_node->next = NULL;
node = new_node;
}
node = llist->head;
printf("llist: ");
while(node != NULL){
printf("%d->", node->current);
node = node->next;
}
return 0;
}

Related

solving balancing parantheses problem in C misunderstanding

I am trying to create a program to solve the classic problem of brackets balancing.
The program needs to tell the user if an the parantheses appearing in an expression are balanced.
I am very new to C/C++, coming from Python, so please excuse my ignorance and please point me towards the right direction!
What I have up until now is below. When compiled with gcc -o exec program.c then ./exec it outputs: List is: ) ( ] [ } { , rather than what I would expect: List is: { } [ ] ( )
I do not understand why, is there an obvious mistake?
I keep searching for it...
Also, I would be very grateful if you could comment if my logic on how I am designing those functions makes sense and is correct: I feel I actually need to put those pointer variables as arguments to the functions?
Thank you!
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
// Parantheses check:
struct Node {
char data;
struct Node* next;
};
struct Node* head_of_listofparans = NULL;
struct Node* head_of_listofparans_open = NULL;
struct Node* head_of_listofparans_close = NULL;
struct Node* insert_at_beginning(char c, struct Node* head) {
struct Node* temp = (struct Node*)malloc(sizeof(struct Node));
temp->data = c;
temp->next = head;
head = temp;
return head;
}
void Delete(int n, struct Node* head) { // removes the n-th node (n=1 represents the head node, n=2 represents the second node)
struct Node* temp1 = head;
if (n==1) {
head = temp1->next;
free(temp1);
return;
}
int i;
for (i=0; i<n-2; i++) { // if n=2 (want to delete the 2nd node), this for-loop doesn't get executed.
temp1 = temp1->next;
} // temp1 now points to the n-1 th node. if n=2, temp1 still (correctly) points towards the head (first node)
struct Node* temp2 = temp1->next; // temp2 points towards the n-th node
temp1->next = temp2->next; // n-1 th node now points to the n+1 th node
free(temp2); // delete the n-th node
}
struct Node* createListOfParantheses(char* parants, struct Node* initial_head) {
struct Node* temp = (struct Node*)malloc(sizeof(struct Node));
temp->data = parants[0];
temp->next = initial_head;
initial_head = temp; // 1st node created. the link of this node points to NULL now. head of the list points to this newly created 1st node.
int i;
for (i=1; i<=(int)strlen(parants); i++) {
initial_head = insert_at_beginning(parants[i], initial_head);
}
return initial_head;
}
// int ParanthesisCheck(char* parantheses_open, char* parantheses_close, char* expr) {
// int n = int(strlen(expr));
// int i;
// for (i=0; i<=n-1; i++) {
// if (strchr(parantheses_open, expr[i])!=NULL) { // if expr[i] can be found in "{[("
// insert_at_beginning(expr[i]) // ppush(expr[i]);
// }
// else if (strchr(parantheses_close, expr[i])!=NULL) { // if expr[i] can be found in "}])"
// if ((check_emptiness_of_stack()==1) || (get_top_of_stack() != expr[i])) { // || signifies the logical OR
// return 0;
// }
// else {
// Delete(1, head_of_stack); // ppop(), delete the very first node (head node), i.e. the most-recently-introduced node
// }
// }
// }
// return check_emptiness_of_stack()==1 ? 1:0;
// }
void Print_List_Of_Parans(struct Node* head) {
struct Node* temp = head;
printf("List is: ");
while (temp != NULL) {
printf(" %c", temp->data);
temp = temp->next;
}
printf("\n");
}
int main() {
char paras[7] = "{}[]()";
char paras_open[4] = "{[(";
char paras_close[4] = "}])";
char input_expr[20] = "(a+b)";
// int j;
// for (j=0; j<7; j++) {
// scanf("%c", &paras[j]); // &paras[j] is equivalent to: paras + j if paras is an array
// printf("%s %d\n", "Iteration number: ", j);
// } // doesn't work because scanf reads 1 character, alright, but adds a \n at its end, so consumes 2 memory locations from the array char paras[7], not 1 as expected.
head_of_listofparans = createListOfParantheses(paras, head_of_listofparans);
head_of_listofparans_open = createListOfParantheses(paras_open, head_of_listofparans_open);
head_of_listofparans_close = createListOfParantheses(paras_close, head_of_listofparans_close);
Print_List_Of_Parans(head_of_listofparans);
// int result = ParanthesisCheck(head_of_listofparans_open, head_of_listofparans_close, input_expr);
// printf("%d\n", result);
return 0;
}

Segmentation fault error while freeing the memory

I tried to make a self-made program for lists. So, I created some basic stuff like creating the list, adding new nodes, showing them, and deleting all the existing nodes in the list.
However, when I put in my list more than 27 elements, it throws me a segmentation fault error while freeing the memory. By the way, when I add like 26 or smaller number of them, it works great. Maybe stack is overflowed or something like that, I really have no idea.
P.S don't tell me that I`m developing a bike, in this way, making something by myself first, I understand things better:)
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
typedef struct node{
struct node * next;
int value;
} node;
int addNode(int position,int value, node ** head,int * size){
int i = 2;
node * curNode = *head;
if(position > *size) return;
while(i <= *size){
if(position == 1){
node * adress = *head;
*head = (node*) malloc(sizeof(node*));
(*head)->next = adress;
(*head)->value = value;
break;
}
else if(i == position){
node * adress = curNode->next;
curNode->next = (node*) malloc(sizeof(node*));
curNode = curNode->next;
curNode->next = adress;
curNode->value = value;
break;
}
else{
curNode = curNode->next;
++i;
}
}
++(*size);
return;
}
void showList(node * head, int size){
int i; node * currentNode = head;
for(i = 0; i < size; ++i){
printf(" %d , next adress: %p |\n", currentNode->value, currentNode->next);
currentNode = currentNode->next;
}
printf("\n");
}
void cleanList(node * head, int size){
int i;
node * curNode = head; node * nextToDelete = NULL;
for(i = 0; i < size; ++i){
nextToDelete = curNode->next;
free(curNode);
curNode = nextToDelete;
}
}
int main() {
node * head = (node*) malloc(sizeof(node*)); //saving head adress to know where the list starts
head->value = 1; //set head value as "1"
int i, size;
node * currentNode = head; //pointer which points to a current node
for(i = 0; i < 5; ++i){
node * adress = (node*) malloc(sizeof(node*)); //variable which saves new node`s adress
currentNode->next = adress; //set this new nod`s adress to previous node`s "next" parametr
currentNode = adress; //set new node`s adress to a current node
currentNode->value = i+2; ///set value for this node
}
size = 6;
addNode(2, 15, &head, &size);
showList(head, size);
showList(head, size);
cleanList(head, size);
return 0;
}
You are allocating memory incorrectly.
Notice these lines:
*head = (node*) malloc(sizeof(node*));
and
curNode->next = (node*) malloc(sizeof(node*));
You are allocating memory for a pointer to struct node instead of the actual struct.
Notice the sizeof function - you pass it the wrong parameter!
Your structure contains an int and a pointer. Those are usually the same size.
But you only allocate memory for a pointer, so, you allocate half the structure.
This will cause you to call free on an invalid address at some point.
It is a miracle your program only crashed during free operation, it should have crashed much sooner.

Printing a Linked list by users input

I am a beginner and I am attending to create and print a linked list by users input. Creating part goes well, but every time I try to print the final list, I get the annoying "LIST IS EMPTY" message. There is probably a problem with *stnode pointer. Could anybody help me please? Thanks for every answer!
Code
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *next;
}*stnode;
//function creating the linked list
void createnodelist(int n)
{
int num, i;
struct node *stnode = (struct node*)malloc(sizeof(struct node)), *fnnode, *temp;
if (stnode==NULL) {
printf("Memory cannot be located");
return;
}
//creating head of the list
else {
printf("Number 1 = ");
scanf("%d", &num);
stnode->data = num;
stnode->next = NULL;
if (stnode == NULL) {
printf("Memory can not be located");
}
temp = stnode;
}
//Creating all others parts of linked list
for (i=2; i<=n; i++)
{
fnnode = (struct node*)malloc(sizeof(struct node));
if (fnnode==NULL) {
printf("Memory cannot be located\n");
break;
}
printf("Number %d = ", i);
scanf("%d", &num);
fnnode->data = num;
fnnode->next = NULL;
temp->next = fnnode;
temp = temp->next;
}
}
//function printing the output
void printnode()
{
struct node *n = (struct node*)malloc(sizeof(struct node));
n = stnode;
if (stnode == NULL) {
printf("LIST IS EMPTY"); //HERE IS MY PROBLEM
}
while (n!=NULL) {
printf("%d ", n->data);
n = n->next;
}
}
int main()
{
int n;
printf("Enter number of elements: ");
scanf("%d", &n);
printf("\n");
createnodelist(n);
printf("\n");
printnode();
printf("\n\n");
return 0;
}
In createnotelist(), you are hiding the global stnode with the local declaration of the stnode. Because of that, the global stnode is remaining undefined or null and is not being modified in createnodelist().
Your createnodelist function does nothing (except leak memory).
It declares a local variable called stnode:
struct node *stnode = (struct node*)malloc(sizeof(struct node)), *fnnode, *temp;
But that local variable is destroyed when the function returns, so there's no way to access the list you've built.
In particular, this stnode is unrelated to the global variable of the same name.
Your printnode function does this:
struct node *n = (struct node*)malloc(sizeof(struct node));
n = stnode;
(Note that this is a memory leak: n = stnode overwrites the pointer returned from malloc, which has now become inaccessible and cannot be freed.)
This stnode is a global variable. It was never set, so it still contains its initial value of NULL.
In createnodelist, write
void createnodelist(int n)
{
int num, i;
stnode = (struct node*)malloc(sizeof(struct node));
struct node *fnnode, *temp;
instead of
void createnodelist(int n) {
int num, i;
struct node *stnode = (struct node*)malloc(sizeof(struct node)), *fnnode, *temp;
Otherwise, you introduce a local variable, which hides the global stnode used in your printnode function later on.
BTW: struct node *n = (struct node*)malloc(sizeof(struct node)); in printnode is superflous, since you overwrite the value of n in the next statement; Writing struct node *n = stnode instead is sufficient.

Linked List Pointer Without A Cast Error

I'm getting assignment makes pointer from integer without a cast errors on lines 46 and 53, the two lines with double asterisks on either side, and for the life of me, I cannot figure out why. Linked lists are very new to me, I don't know how they work completely yet.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
struct node_def
{
int data;
struct node_def *next;
};
typedef struct node_def node;
node *makeNode (int a);
node *insertFront(node *head,node *new);
void printList(node *head);
int numNodes = 0;
int main()
{
srand(time(0));
int r = rand() % 10000;
int i = 0;
node *head = NULL;
node *tmp = NULL;
printf("How many nodes? ", numNodes);
scanf("%d", numNodes);
printf("\n");
head = insertFront(head, tmp);
for(i = 0; i < numNodes; i++)
{
makeNode(r);
printList(head);
}
printf("\n");
return 0;
}
node *makeNode (int a)
{
node *new = malloc(sizeof(node));
**new = a;**
return new;
}
node *insertFront(node *head, node *new)
{
**new->data = head;**
new->next = new;
return 0;
}
void printList(node *head)
{
int j = 0;
for(j = 0; j < numNodes; ++j)
{
while (head != NULL)
{
printf(" %4d", head->data);
head = head->next;
}
if(j % 10 == 0)
printf("\n");
}
return;
}
new = a is meant to make new nodes and assign them a random number from 0 - 9999.
You try to assign r to new, but new is a struct.
You make a pointer to struct : node *new
What you want to do is assigning r to new->data, which is an int.
node *insertFront(node *head, node *new)
{
**new->data = head;** // ** is meaningless
new->next = new; // new is a reserved key word, don't use it this way
return 0;
}
What you try to do is to put a NULL pointer as the head of your list.
Just push element into it within your makeNode function.
insert like this :
void createNode(node *head)
{
Node *new_node = malloc(sizeof(Node*));
new_node->data = rand() % 100000;
new_node->next = NULL;
if(head == NULL)
head = new_node;
else if(head != NULL)
//Here you have to adapt your list, search (linked list crud functions)
}
You have a bad understanding about what pointers are.
Hope it helps bro

What's with the program why is it not printing any result?

struct node{
int data; struct node *next;
};
void push(struct node* head, struct node* n){
if(n!= NULL){
if(head==NULL)
head = n;
else {
n->next = head;
head = n;
}
} else printf("Cannot insert a NULL node");
}
struct node* pop(struct node* head){
if(head!=NULL){
struct node *n = head;
head = head->next;
return n;
} else {
printf("The stack is empty");
return NULL;
}
}
int main(){
int i;
struct node *head = NULL, *n;
for(i=15;i>0;i--){
struct node *temp = malloc(sizeof(struct node));
temp -> data = i;
temp->next = NULL;
push(head,temp);
}
n = head;
while(n!=NULL){
printf("%d ",n->data);
n=n->next;
}
return 0;
}
You need to pass the address of the pointer head to the function push. I your case the head is not getting modified because you are only passing the value in the head.
void push(struct node** head, struct node* n){
if(n!= NULL){
if(*head==NULL)
*head = n;
else {
n->next = *head;
*head = n;
}
} else printf("Cannot insert a NULL node");}
int main(){
int i;
struct node *head = NULL, *n;
for(i=15;i>0;i--){
struct node *temp = (struct node *)malloc(sizeof(struct node));
temp -> data = i;
temp->next = NULL;
push(&head,temp);
}
n = head;
while(n!=NULL){
printf("%d ",n->data);
n=n->next;
}
return 0;}
You are passing the head pointer by value to the function push(head,temp);. The changes to head done inside push will not be reflected in the main() function.
You should pass address of head to push().
push(&head, temp);
and inside push():
*head = n;
Similar change will be required for pop(). You can verify what I am saying by adding a printf inside the loop in main() as: printf("%p\n", head);. The value of head will remain unchanged.
BTW, it is good practice to add a \n at the end of statement inside printf, it flushes the stdout stream immmediately hence your output is printed immediately on stdout (your computer screen).

Resources