I'm building a program that simulates a bus going through bus stops and picking up a random amount of passengers (0-15) the problem is that when i try to print the amount of passengers that got in on a bus stop i get a lot of numbers bigger than 15.
Here's a part of my program:
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node* next;
};
void printList(struct Node* n)
{
while (n != NULL) {
printf(" %d ", n->data);
n = n->next;
}
}
int main()
{
struct Node*ΤΣ_ΚΤΕΛ = NULL;
struct Node*ΓΕΦΥΡΑ = NULL;
ΤΣ_ΚΤΕΛ = (struct Node*)malloc(sizeof(struct Node));
ΓΕΦΥΡΑ = (struct Node*)malloc(sizeof(struct Node));
ΤΣ_ΚΤΕΛ->data = rand()%15+1;
ΤΣ_ΚΤΕΛ->next = ΓΕΦΥΡΑ;
printList(ΓΕΦΥΡΑ);
return 0;
}
Below has some tweaks that fix your basic issues, with explanations in the comments:
#include <stdio.h>
#include <stdlib.h>
#include <time.h> // you should seed the rand function to get pseudorandom numbers
// each time you run
struct Node {
int data;
struct Node* next;
};
void printList(struct Node* n)
{
while (n != NULL) {
printf(" %d ", n->data);
n = n->next;
}
}
int main(void)
{
// seed the rand function with the current time, this is common
// see link below for further info
srand(time(NULL));
struct Node*ΤΣ_ΚΤΕΛ = NULL;
struct Node*ΓΕΦΥΡΑ = NULL;
ΤΣ_ΚΤΕΛ = malloc(sizeof(struct Node));
ΓΕΦΥΡΑ = malloc(sizeof(struct Node));
// always check the return value of malloc
if (ΤΣ_ΚΤΕΛ == NULL || ΓΕΦΥΡΑ == NULL)
{
// handle errors how you want
fprintf(stderr, "out of memory!\n");
exit(-1);
}
ΤΣ_ΚΤΕΛ->data = rand()%15+1;
ΤΣ_ΚΤΕΛ->next = ΓΕΦΥΡΑ;
// must fill in data for ΓΕΦΥΡΑ also
ΓΕΦΥΡΑ->data = rand()%15+1;
ΓΕΦΥΡΑ->next = NULL;
// passing in ΤΣ_ΚΤΕΛ will print both structures now
printList(ΤΣ_ΚΤΕΛ);
return 0;
}
Demonstration.
Also see:
How to generate a random int in C?
Do I cast the result of malloc?
Related
I am trying to print the values of the single linked list in c, but its printing the garbage values after printing the values entered. I have written the create function to create the linked list by using the do-while loop, and also the display function to print the linked list. My question is why it is printing the garbage value after entering the values.
Please help me to find out where I did wrong in my code to help further my coding practices.
Tried Code:
#include <stdio.h>
#include <stdlib.h>
//Declaring the struct variable
struct Node
{
int data;
struct Node *link;
}*head=NULL;
//Creating the Linked List
void create()
{
char ch= 'y';
do
{
printf("ch : %c",ch);
struct Node *p,*q;
p = (struct Node*)malloc(sizeof(struct Node*));
printf("\nEnter the Data : \n");
scanf("%d", &p->data);
p->link = NULL;
if(head == NULL)
{
head = p;
}
else
{
q->link = p;
}
q=p;
scanf("%c",&ch);
}while(ch!= 'n');
}
//Displaying the Linked List
void display()
{
struct Node *p=head;
if(p == NULL)
{
printf("\n List is Empty \n");
}
else
{
while(p!=NULL)
{
printf("%d -->", p->data);
p = p->link;
}
}
}
int main()
{
printf("\n Enter the data into the linked list: \n");
create();
printf("\nCreation Complete........ Displaying\n");
display();
return 0;
}
Output:
1
2
3
4
5
6
n
Creation Complete........ Displaying
1 --> 2 --> 3 --> 4 --> 5 --> 6 -->7097656 -->
Here's an example on a 64-bit Windows host:
test.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Node
{
int data;
struct Node *link;
}*head=NULL;
int main(int argc, char* argv[])
{
printf ("sizeof(struct Node): %lld, sizeof(struct Node*): %lld\n",
sizeof(struct Node), sizeof(struct Node*));
return 0;
}
Output:
sizeof(struct Node): 16, sizeof(struct Node*): 8
In other words, you probably want malloc(sizeof(struct Node)
This is my algorithm for adding nodes to a linked list which is in a sorted way for surnames of persons.
Here is the code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct Node {
char Name[1024];
char Surname[1024];
char Telno[1024];
struct Node* next;
};
void Add(struct Node** firstnode, struct Node* NewNode)
{
struct Node* tempo;
//printf("%d",strcmp((*firstnode)->Surname,NewNode->Surname));
if (*firstnode == NULL || (strcmp((*firstnode)->Surname,NewNode->Surname) > 0)) {
NewNode->next = *firstnode;
*firstnode = NewNode;
}
else {
tempo = *firstnode;
while (tempo->next != NULL && strcmp(tempo->Surname,NewNode->Surname) < 0) {
tempo = tempo->next;
}
NewNode->next = tempo->next;
tempo->next = NewNode;
}
}
struct Node* CreateNode(char name[1024], char surname[1024], char telno[1024])
{
struct Node* NewNode = (struct Node*)malloc(sizeof(struct Node));
strcpy(NewNode->Name,name);
strcpy(NewNode->Surname,surname);
strcpy(NewNode->Telno,telno);
NewNode->next = NULL;
return NewNode;
}
void Printlinkedlist(struct Node* head)
{
struct Node* temp = head;
while (temp != NULL) {
printf("%s %s %s\n", temp->Name,temp->Surname,temp->Telno);
temp = temp->next;
}
}
struct Node* head = NULL;
struct Node* temp;
int main()
{
int personcount;
char name[1024],surname[1024],telno[1024];
printf("Please give the count of person:");
scanf("%d", &personcount);
for (int i = 0; i < personcount; i++) {
printf("Please give the name of %d. person:", i + 1);
scanf(" %s", &name);
printf("Please give the surname of %d. person:", i + 1);
scanf(" %s", &surname);
printf("Please give the phone number of %d. person:", i + 1);
scanf(" %s", &telno);
temp = CreateNode(name,surname,telno);
Add(&head, temp);
}
printf("\n -------------- Linkedlist --------------\n");
Printlinkedlist(head);
return 0;
}
The first problem is this: For example, if I enter people's surnames as G, A, L, E, K (So first person's last name will be "G", second person's last name will be "A" etc..), it gives an incorrectly ordered output.
And the second one is: If I delete the comment line characters behind the printf inside the add function, I get a segmentation fault that I don't understand why
Thanks for the answer.
It should first be said that you could, and should, have figured it out yourself by either:
Debugging the program:
On Linux: How Can I debug a C program on Linux?
On Windows: How do you debug a C program on Windows?
Enabling core dumps and analyzing the core file you get when your program crashes; see this explanation.
But, more to the point, let's have a look at (some of) your code:
if (*firstnode == NULL || /* another condition */) {
// do stuff
}
else {
// so *firstnode may be NULL here
tempo = *firstnode;
while (tempo->next != /* some value */ && /* another condition*/ ) {
// do stuff
}
// do stuff
}
See the problem? tempo could get assigned a NULL point, and then de-referenced to get to the next field. That would likely cause a segmentation fault.
I am trying basic creation of linked list using C. I have written the following code which is working up until first node but fails eventually on second one. I think the issue is where I am trying to display the node values in list separated by arrow(->). I think my logic is right but please correct me. Thanks in advance
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
struct node
{
int number;
struct node *next;
};
typedef struct node NODE;
NODE *node1, *node2, *start, *save;
int main()
{
node1 = (NODE *)malloc(sizeof(NODE));
int i = 0;
start = NULL;
for(i = 0; i < 3; i++)
{
int inf;
printf("Enter node value:");
scanf("%d", &inf);
node1->number = inf;
node1->next = NULL;
if(start == NULL)
{
start = node1;
save = node1;
}
else
{
// save=start;
// start=node1;
// node1->next=save;
node1->next = start;
start = node1;
}
while(node1 != NULL)
{
printf("%d ->",node1->number);
node1 = node1->next;
}
}
return 0;
}
The issues are
How you're allocating your nodes for insertion (i.e. save for one, you're not).
How they're placed in the list once you fix the above.
Don't cast malloc in C programs (read here for why).
Fail to check the success of your scanf invoke.
Fail to check the success of your malloc invoke
Before you get discouraged, things you did correctly:
Did not mask a node pointer in a typedef
Properly included a MCVE for review
Prospected the things you may be doing wrong.
A very simple example of iterating three values into a linked list would look something like this:
#include <stdio.h>
#include <stdlib.h>
struct node
{
int number;
struct node *next;
};
typedef struct node NODE;
int main()
{
NODE *head = NULL, *p;
int i = 0;
for(i = 0; i < 3; i++)
{
int inf;
printf("Enter node value:");
if (scanf("%d", &inf) == 1)
{
p = malloc(sizeof *p);
if (p != NULL)
{
p->number = inf;
p->next = head;
head = p;
}
else
{
perror("Failed to allocate new node");
return EXIT_FAILURE;
}
}
else
{
// failed to read data. break
break;
}
// report current linked list
printf("%d", p->number);
for (p=p->next; p; p = p->next)
printf(" -> %d", p->number);
fputc('\n', stdout);
}
// cleanup the linked list
while (head)
{
p = head;
head = head->next;
free(p);
}
head = NULL;
return 0;
}
Input
The values 1 2 3 are input upon being prompted:
Output
Enter node value:1
1
Enter node value:2
2 -> 1
Enter node value:3
3 -> 2 -> 1
Best of luck.
You should use malloc() inside for loop.
Since it is outside, same memory is being used.
As said by Vamsi, you should use malloc to put the nodes on the heap. You also generally shouldn't cast the output of malloc, it isn't needed. And then you could play around with making a doubly-linked list, where you also have a prev pointer inside your struct.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#define n 5
struct node
{
int num;
char *symbol;
char *code;
struct node *left;
struct node *right;
}*root_ptr, *current, *previous;
void form_bst_of_dividing_positions();
void inorderTraversal(struct node *);
int dividing_positions[n], counter = 0;
int main(int argc, char *argv[])
{
//code to populate dividing_positions
//tree structure formation
counter = 0;
root_ptr = malloc(sizeof(struct node));
root_ptr->num = dividing_positions[0];
root_ptr->code = root_ptr->symbol = NULL;
root_ptr->left = root_ptr->right = NULL;
form_bst_of_dividing_positions();
inorderTraversal(root_ptr);
return 0;
}
void form_bst_of_dividing_positions()
{
for(i=1;i<n;i++)
{
if(dividing_positions[i]==-1)
break;
else
{
struct node nodeToAdd;
nodeToAdd.num = dividing_positions[i];
nodeToAdd.code = nodeToAdd.symbol = NULL;
nodeToAdd.left = nodeToAdd.right = NULL;
current = previous = root_ptr;
while(current!=NULL)
{
previous = current;
current = (dividing_positions[i]<(current->num))? current->left : current->right;
}
if(nodeToAdd.num<(previous->num))
previous->left = &nodeToAdd;
else
previous->right = &nodeToAdd;
}
}
}
void inorderTraversal(struct node *no)
{
if(no!=NULL)
{
inorderTraversal(no->left);
printf("%d ", no->num);
inorderTraversal(no->right);
}
}
Above code gives me Segmentation fault .. in Codeblocks the output window prints 4 infinitely. 2, 3, 1, 4 = to be inserted into BST. Ive converted my Java code to C, are there any specifics to be handled in my above code?
Thanks..
Your nodeToAdd is a local variable, its address becomes invalid once you leave that code block. You should use malloc to create new nodes (and free them with free eventually).
Use malloc everytime you add a new node.
I'm trying to recurvisely implement an insert function in C, but I'm having all sorts of issues. I'm in an intro CS class and they started throwing C labs at us before we had ever worked with it before. Part of the issue is that the list pointer is not being recognized as NULL and I'm also pretty sure that I'm using malloc improperly.
#include <stdio.h>
#include <stdlib.h>
#define True 1
#define False 0
typedef int BOOLEAN;
struct Node{
int value;
struct Node *next;
};
void insert(int x, struct Node **pL){
printf("insert\n");
if(*pL == NULL){
printf("inside if\n");
struct Node *pN;
pN = (struct Node*) malloc(sizeof(struct Node));
(*pN).value = x;
(*pN).next = NULL;
return;
}
if (*pL != NULL){
printf("inside else\n");
insert(x, &(((*pL)->next)));
}
printf("end insert\n");
};
void printList(struct Node *L){
while (L != NULL){
printf("%d", (*L).value);
printList((*L).next);
}
return;
};
main(){
printf("main\n");
struct Node* L;
//L).next = NULL;
int i;
printf("for loop\n");
for (i = 3; i < 20; i+=2){
printf("%d\n", i);
insert(i, &L);
}
printList(L);
};
First of all, in main you need to initialise L:
struct Node* L = NULL;
Second, in insert when you allocate the new node pN, you are not assigning it to the pL, i.e., it doesn't get inserted. Put this right before the return; in insert:
*pL = pN;
(Also you could remove the return and change if (*pL != NULL) into else.)
Then, in printList you are both iterating with a while loop, and with recursion. Choose one, not both, e.g.,:
while (L) {
printf("%d\n", L->value);
L = L->next;
}
Also, throughout your code you can replace (*pointer_to_struct).field with pointer_to_struct->field for better style.