What does the -> operator do in C? [duplicate] - c

This question already has an answer here:
What does this mean "->"?
(1 answer)
Closed 6 years ago.
I have to learn this by 10 am tomorrow for a final because I'm a procrastinator.
I know can all scold me if you like. What I have here is I have to understand pointers to understand linked lists and the one thing that boggles my mind when working with pointers is when -> is used.
From what I've googled, it changes what a variable points to?
This confuses me when there are lines in the example code my professor gave me, such as temp = temp->head in this code or when it states printf("%d", temp->num);
Can anyone please help explain this? Thank you in advance.
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
struct node
{
int num;
struct node *ptr;
};
typedef struct node NODE;
int main()
{
NODE *head, *temp = 0, *first;
int count = 0;
int choice = 1;
while(choice)
{
head = (NODE *)malloc(sizeof(NODE));
printf("Enter the value: \n");
scanf("%d", &head->num);
if (first != 0)
{
temp->ptr = head;
temp = head;
}
else
first = temp = head;
fflush(stdin);
printf("Do you want to continue?");
scanf("%d", &choice);
}
temp->ptr = 0;
temp = first;
printf("\nStatus of the linked list");
while (temp != 0)
{
printf("%d->" temp->num);
count++;
temp = temp->ptr;
}
printf("NULL\n");
printf("Number of entries in linked list %d", count);
return 0;
}
}

It dereferences a pointer to a structure, and access a member of the structure.
Take for example, from your code:
temp->ptr = head;
This is the same as
(*temp).ptr = head;
The "arrow" operator make it a little simpler.
There is some history behind the -> operator if you're curious.

Related

printf segmentation fault and wrong sorted linked list

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.

Linked lists in C with chars and integers (troubleshooting)

I want to programm a linked list in C, trying to apply everything I've learned so far.
I wrote this program to create a linked list:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node *head = NULL;
//Define struct node
struct node{
char * name;
int num;
struct node * next;
};
//Print List
void printList(){
struct node * temp = head;
while (temp != NULL){
printf("%s", temp->name);
printf("%d", temp->num);
temp = temp->next;
}
}
//Create New Node
struct node * newNode (char * name, int num){
struct node * newNode = (struct node*)malloc(sizeof(struct node));
newNode->name = name;
newNode->num = num;
newNode->next = NULL;
return newNode;
}
//Function to insert and sort Elements
void insertSorted (char * name, int num){
//Empty Liste -> Head is NULL
if (head == NULL){
head = newNode(name, num);
}
else if (strcmp(name, head->name) <=0){
// strcmp-output = -1 ->string 1 > string 2; 0 -> both strings are the same
struct node * temp = newNode(name, num);
temp->next = head;
head = temp;}
struct node * current = head; struct node *prev = NULL;
if (strcmp(name, current->name)>0){ //-> 1, string1 < string 2 ->insert after
while(current != NULL && strcmp(name, current->name)<=0){
prev = current;
current = current->next;
}
struct node * temp = newNode(name, num);
prev->next = temp;
temp->next = current;
}
}
//Test of the linked list
int main()
{
char name; int num;
//Testprogram
printf("Enter a name\n");
scanf("%s", &name);
printf("Enter a number\n");
scanf("%d", &num);
insertSorted(&name, num);
char name2; int num2;
printf("Enter a name\n");
scanf("%s", &name);
printf("Enter a number\n");
scanf("%d", &num2);
insertSorted(&name2, num2);*/
char name3; int num3;
printf("Enter a name\n");
scanf("%s", &name);
printf("Enter a number\n");
scanf("%d", &num3);
insertSorted(&name3, num3);
printList();
return 0;
}
Output example:
Input: Anna 1, Claudio 2, Berta 3
Output: 32Berta1
It somehow...makes the Names vanish and the numbers are in the wrong order too. I'm pretty new to programming, so I have troubles fixing this by myself.
Any help would be hugely appreciated :) Not only to fix the error, but also tips on how to program more...elegantly, so to say.
Thanks :)
//Edit:
Thank you for all the input so far! I messed up the input of the string while testing the program.
As suggested I tried to skip the part with the input, testing the linked list like this in main() (thanks Julien!):
insertSorted("Anna", 1);
insertSorted("Claudio", 2);
insertSorted("Berta", 3);
printList();
it results in the programm not executing and exiting with a negative number error code. Does this point to an infinite loop?
I haven't looked at the linked list details, but one issue I see is that you are using single char variable to store the names (which should be an array or characters). This lack of enough space to store the input make you program have an undefined behaviour after the call to scanf.
As #franji1 stated, try working step by step. If you want to check the code of your list, try testing:
insertSorted("Anna", 1);
insertSorted("Claudio", 2);
insertSorted("Berta", 3);
And check the result is what you expect. Once this is working, add the code asking for input from the user using scanf.
Im not an expert at C but since you mentioned code elegancy I can tell you this. You didn't need to use all these different if statements, you could use the while loop from the begining and insert after you find a name that is bigger than current. This will work even if it has to be inserted before the head node as long as you check that prev is not null. I hope I helped you and that you will find a solution to your problem!

Linked List insertion in Beginning

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.

Segmentation Fault when using Linked Lists and Char arrays

I'm struggling through my programming homework and need a hand with Linked Lists. Basically we have to create a program that contains certain functions to manage linked lists. Fairly standard. I tried it last week and just couldn't get it. I'm trying to get it working this weekend and was making good progress until I ran into segmentation faults.
struct STUDENT
{
char *FirstName;
char *LastName;
char *PUID;
int age;
struct STUDENT *next;
};
This is the structure I'm trying to use. The first three values are char arrays and the fourth is just a number. Following this I tried to declare a starting and current node globally.
struct STUDENT *head = NULL;
struct STUDENT *curr = NULL;
Following this I have my create node function, which takes a user input and puts it into the list.
void *createListNode()
{
char first[MAXNAME];
char last[MAXNAME];
char ID[MAXID];
char *pfirst;
char *plast;
char *pID;
int tage;
struct STUDENT *temp = (struct STUDENT *) malloc (sizeof(struct STUDENT));
printf("Enter a first name: ");
scanf("%s", first);
pfirst = first;
printf("entered name: %s\n", pfirst);
printf("Enter a last name: ");
scanf("%s", last);
plast = last;
printf("entered name: %s\n", plast);
printf("Enter the Purdue ID: ");
scanf("%s", ID);
pID = ID;
printf("ID: %s\n", pID);
printf("Enter an age: ");
scanf("%d", &tage);
printf("age: %d\n", tage);
temp->FirstName = strdup(first);
printf("first\n");
temp->LastName = strdup(last);
printf("last\n");
temp->PUID = strdup(ID);
printf("id\n");
temp->age = tage;
printf("age\n");
temp->next = NULL;
printf("next\n");
if (curr == NULL)
{
printf("inside if\n");
head->next = temp; //-------SEGMENTATION FAULT---------------------
printf("line 107\n");
head = curr = temp;
printf("line 109\n");
}
else
{
curr = temp;
}
}
Background of what I'm done up to this point:
I was getting segmentation faults when I tried to assign my arrays to my 'temp' node, but by using malloc on it I solved that problem. Using print statements, I've tracked the problem to the indicated line. When I try to run the code, I get a segmentation fault. I tried the same malloc code above on the 'head' and 'curr' nodes, but that gave me:
carlton#carlton-Inspiron-N7010:~/CNIT315$ gcc lab5.c
lab5.c:20:64: error: invalid initializer
struct STUDENT head = (struct STUDENT *) malloc (sizeof(struct STUDENT));
This is where I believe the problem is, but I've been searching and experimenting for several hours and haven't gotten anywhere. And I just realized this is now a very long post. Thanks for reading it through and I appreciate any push in the right direction!
You initialize head to NULL. You can't dereference head before assigning a valid pointer to it. head->next = temp; gives you a segfault because head is a null pointer.
Thus, you need to review this part of the code:
if (curr == NULL)
{
printf("inside if\n");
head->next = temp; //-------SEGMENTATION FAULT---------------------
printf("line 107\n");
head = curr = temp;
printf("line 109\n");
} else
{
curr = temp;
}
Since it seems like you want to insert at the end of the list, I would suggest something like this:
temp->next = NULL;
if (head == NULL) {
curr = head = temp;
} else {
curr->next = temp;
curr = temp;
}
This makes curr always point to the last node, and head always points to the beginning of the list.
Am I wrong or do you set head->next = temp; but never set head to a valid object before?
You either have to initialize head with an 'empty' Student at the beginning or you just have to set head = temp;
Assuming that you've defined the head variable outside the createListNode() function, here's the problem:
Memory is never assigned to it, since you have never called malloc()

malloc() causing EXC_BAD_ACCESS error in Xcode

I am trying to implement the Linked List data structure for my college course, but on executing the code the following line produces an EXC_BAD_ACCESS(code=1, address=0x8) error.
temp->next = (ptrtonode) malloc(sizeof(struct node));
Following is the code in its entirety.
#include <stdio.h>
#include <stdlib.h>
typedef struct node *ptrtonode;
typedef ptrtonode header;
struct node
{
int data;
ptrtonode next;
};
ptrtonode create(int n)
{
int i;
header temphead = NULL;
ptrtonode temp = temphead;
for(i=0;i<n;i++)
{
temp->next = (ptrtonode) malloc(sizeof(struct node));
printf("Enter data for node %d: ", i+1);
scanf("%d", &temp->next->data);
temp = temp->next;
}
temp->next = NULL;
return temphead;
}
int main(int argc, const char * argv[])
{
header head;
int n;
printf("How many nodes do you wish to create?");
scanf("%d", &n);
head = create(n);
}
Any help would be appreciated.
Thanks all!
On first iteration of the for loop inside the create() function temp is NULL, which is then dereferenced causing the failure (not malloc() causing the failure). You will need to restructure the code slightly to prevent dereferencing a NULL pointer.
Other points:
casting the return value of malloc() is not required.
check the result of scanf() to ensure n was assigned a valid integer (and confirm that the int is positive):
/* scanf() returns the number of assignments made,
which in this case should be 1. */
if (1 == scanf("%d", &n) && n > 0)
{
/* 'n' assigned a sensible value. */
}

Resources