I'm taking a course on C and I'm having a lot of trouble initializing a double pointer. I have made my best effort to reduce the practical exercise to this code where the error can be reproduced:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct _tCoordinateNode
{
struct _tCoordinateNode *next;
} tCoordinateNode;
typedef struct _tDateTimeNode
{
int a;
tCoordinateNode *coordinatesList;
struct _tDateTimeNode *next;
} tDateTimeNode;
typedef struct _ApiData
{
tDateTimeNode *timeNodeList;
} tApiData;
void dateTimeNode_insert(tDateTimeNode **_list)
{
if ((*_list) == NULL)
{
(*_list) = (tDateTimeNode *)malloc(sizeof(tDateTimeNode));
(*_list)->a = 1;
(*_list)->coordinatesList = NULL;
(*_list)->next = NULL;
}
}
tDateTimeNode *api_getTemporalData(tApiData *data)
{
return data->timeNodeList;
}
int main()
{
tApiData data;
data.timeNodeList = NULL;
dateTimeNode_insert(&(api_getTemporalData(&data)));
printf("%d", data.timeNodeList->a);
}
I'm getting a segmentation fault error, but I cannot see why. Any idea what's causing the error? I suppose it should work and the variable should be set to 1.
Related
I'm kinda new in C. I'm having some trouble using pointers and stuff like that.
I made this piece of code to try to understand why does it return me Segmentation Fault.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct lligada {
int userID;
struct lligada *prox;
} *LInt;
typedef struct {
int repo_id;
LInt users;
} Repo;
typedef struct nodo_repo {
Repo repo;
struct nodo_repo *left;
struct nodo_repo *right;
} *ABin_Repos;
void createList (int id_user, int id_repo) {
ABin_Repos temp = malloc(sizeof(struct nodo_repo));
temp->repo.repo_id = id_repo;
temp->repo.users->userID = id_user;
temp->left = NULL;
temp->right = NULL;
printf("%d", temp->repo.users->userID);
}
int main() {
int id_user, id_repo;
scanf("%d %d", &id_user, &id_repo);
createList(id_user, id_repo);
return 0;
}
I really don't understand.
Sorry if this is a stupid question.
Thank you!
The type of users is LInt and LInt is an alias of type struct lligada *:
typedef struct lligada {
int userID;
struct lligada *prox;
} *LInt;
That means the type of users is struct lligada *.
In the createList(), you are accessing users pointer before allocating it. Hence, you are getting segmentation fault.
You should do:
void createList (int id_user, int id_repo) {
ABin_Repos temp = malloc(sizeof(struct nodo_repo));
// Allocate memory to users
temp->repo.users = malloc (sizeof (struct lligada));
// check malloc return
if (temp->repo.users == NULL) {
// handle memory allocation failure
exit (EXIT_FAILURE);
}
temp->repo.repo_id = id_repo;
temp->repo.users->userID = id_user;
.....
.....
Additional:
Follow good programming practice, make sure to check returned value of function like scanf() and malloc().
After putting elements in my linked list, when i want to acces them i got a segmentation fault. I try to insert from the head(head is tete), when reading the element I have no problems only in that function
here is the line that causes segmentation fault error:
if((p->ID.num)>(p2->ID.num))
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <conio.h>
typedef struct identifiant//identifiant
{
char section[50];
int num;
}identifiant;
typedef struct Date //DATE
{
int jj;
int mm;
int an;
}Date;
typedef struct notes
{
float note;
struct notes* nnext;
}notes;
typedef struct LTE
{
identifiant ID;
char Nom[25];
char Prenom[25];
Date Date_naissance;
notes* Tnotes;
float Moy;
struct LTE* next;
}LTE;
typedef struct coefs
{
int coef;
struct coefs* next;
}coefs;
coefs* COEF;
LTE* tete;
int main()
{ int NE,NN;
LTE* p;
LTE* n;
LTE* m;
coefs* q;
int i,x;
x=0;
NE = Saisie_NE();
NN = Saisie_NN();
{
tete=(LTE*)malloc(sizeof(LTE));
tete->next=0 ;
Saisie_E(1,tete,NN);
for(i=2;i<=NE;i++)
{
LTE* tmp=(LTE*)malloc(sizeof(LTE));
Saisie_E(i,tmp,NN);
tmp->next=tete;
tete=tmp;
}
}....
//remplir tabeleau des coefs
{
COEF=(coefs*)malloc(sizeof(coefs));
COEF->next=0 ;
q=COEF;
for(i=0;i<NN;i++){
Saisie_coef(i+1,q,NN,&x);
coefs* tmp=(coefs*)malloc(sizeof(coefs));
q->next=tmp;
q=q->next;
}
q->next=0;
}
//everything works fine until the this function↓↓↓
{
p=tete;
Trier(p,NE);
}
//here is the functuion ty guys sorry for bad presentation
void Trier(LTE* p,int NE)
{
int tr,i;
LTE* q;
LTE* p1;
LTE* p2;
p1=p;
i=0;
while(tr!=1)
{ tr=1;
p=p1;
for(i=0;i<NE;i++)
{ p2=p->next;
//here is the segment fault error
if((p->ID.num)>(p2->ID.num))
{q=p->next->next;
p->next->next=p;
p->next=q;
tr=0;
}
p=p->next;
}
}
The problem lies in the below loop. During the loop iterations, when i == (NE-1), p will be pointing to the last node and p->next will be NULL which gets assigned to p2. So, accessing p2->ID.num leads to segmentation fault.
You can either add a check for p2!=NULL or modify your loop logic to prevent this from happening.
for(i=0;i<NE;i++)
{ p2=p->next; /* ==> When p becomes the last node, p2 will become NULL */
//here is the segment fault error
if((p->ID.num)>(p2->ID.num))
{q=p->next->next;
p->next->next=p;
p->next=q;
tr=0;
}
p=p->next;
}
I'm trying to create a simple singly linked list in C, and have encountered an infinite "Singal 11 being dropped" loop while running my program in Valgrind.
My .h file:
#ifndef TEST_H
#define TEST_H
struct fruit {
char name[20];
};
struct node {
struct fruit * data;
struct node * next;
};
struct list {
struct node * header;
unsigned count;
};
#endif
My .c file:
#include "test.h"
#include <stdio.h>
#include <string.h>
void init_list(struct list my_list)
{
my_list.header = NULL;
my_list.count = 0;
}
void add_to_list(struct list my_list, struct fruit my_fruit)
{
struct node my_node;
struct node nav_node;
my_node.data = &my_fruit;
my_node.next = NULL;
if(my_list.count == 0) { /* set head node if list is empty */
my_list.header = &my_node;
my_list.count++;
} else {
nav_node = *my_list.header;
while (nav_node.next != NULL) { /* traverse list until end */
nav_node = *nav_node.next;
}
nav_node.next = &my_node;
my_list.count++;
}
}
int main()
{
struct fruit fruit_array[5];
struct list fruit_list;
int i;
strcpy(fruit_array[0].name, "Apple");
strcpy(fruit_array[1].name, "Mango");
strcpy(fruit_array[2].name, "Banana");
strcpy(fruit_array[3].name, "Pear");
strcpy(fruit_array[4].name, "Orange");
init_list(fruit_list);
for(i=0; i < 5; i++) {
add_to_list(fruit_list, fruit_array[i]);
}
return 0;
}
I'm assuming the issue stems from my list traversal in add_to_list, but I'm unsure about what I'm doing wrong.
Thanks!
You're passing structs by value into functions. This will create a copy of the struct in the function, and changes to the copy will not occur on the struct in the calling function.
You should read about pointers in your favorite c-language book.
Why cant i access the pointer "Cells" like an array ? i have allocated the appropriate memory why wont it act like an array here? it works like an array for a pointer of basic data types.
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#define MAX 10
struct node
{
int e;
struct node *next;
};
typedef struct node *List;
typedef struct node *Position;
struct Hashtable
{
int Tablesize;
List Cells;
};
typedef struct Hashtable *HashT;
HashT Initialize(int SIZE,HashT H)
{
int i;
H=(HashT)malloc(sizeof(struct Hashtable));
if(H!=NULL)
{
H->Tablesize=SIZE;
printf("\n\t%d",H->Tablesize);
H->Cells=(List)malloc(sizeof(struct node)* H->Tablesize);
should it not act like an array from here on?
if(H->Cells!=NULL)
{
for(i=0;i<H->Tablesize;i++)
the following lines are the ones that throw the error
{ H->Cells[i]->next=NULL;
H->Cells[i]->e=i;
printf("\n %d",H->Cells[i]->e);
}
}
}
else printf("\nError!Out of Space");
}
int main()
{
HashT H;
H=Initialize(10,H);
return 0;
}
The error I get is as in the title-error: invalid type argument of '->' (have 'struct node').
A correct version of your code is given below. It is always advisable not to use pointers while using typedef.
The only problem with your code apart from that was your access method.
H->cells[i]->next will throw an error.
Also H->cells->[i]e was invalid syntax.
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#define MAX 10
struct node
{
int e;
struct node *next;
};
typedef struct node List;
typedef struct node Position;
struct Hashtable
{
int Tablesize;
List *Cells;
};
typedef struct Hashtable HashT;
HashT Initialize(int SIZE,HashT *H)
{
int i;
H=(HashT*)malloc(sizeof(struct Hashtable));
if(H!=NULL)
{
H->Tablesize=SIZE;
printf("\n\t%d",H->Tablesize);
H->Cells=(List*)malloc(sizeof(List)*H->Tablesize);
//should it not act like an array from here on?
if(H->Cells!=NULL)
{
for(i=0;i<H->Tablesize;i++)
//the following lines are the ones that throw the error
{
H->Cells[i].next=NULL;
H->Cells[i].e=i;
printf("\n %d",H->Cells[i].e);
}
}
}
else printf("\nError!Out of Space");
return *H;
}
int main()
{
HashT H;
H=Initialize(10,&H); //return is not required as already we are passing by address
return 0;
}
The
H->Cells[i]->next
should be
H->Cells[i].next
(Similarly for e.)
This is a version of your program without the typedefs. Which one is more readable?
#include <stdio.h>
#include <stdlib.h>
struct node {
struct node *next;
int e;
};
struct Hashtable {
unsigned Tablesize;
struct node *Cells;
};
struct Hashtable *Initialize(unsigned size)
{
unsigned iii;
struct Hashtable *hp;
hp = malloc (sizeof *hp);
if(!hp) {
fprintf(stderr, "Error!Out of Space\n");
return NULL;
}
hp->Cells = malloc(size * sizeof *hp->Cells );
if(!hp->Cells) {
hp->Tablesize = 0;
return hp;
}
hp->Tablesize = size;
fprintf(stderr, "\t%u\n", hp->Tablesize);
for(iii=0; iii < hp->Tablesize; iii++) {
hp->Cells[iii].next = NULL;
hp->Cells[iii].e = iii;
fprintf( stderr, " %u\n", hp->Cells[iii].e);
}
return hp;
}
int main()
{
struct Hashtable *hashtab;
hashtab = Initialize(10);
return 0;
}
The changes:
removed the typedefs; since they are confusing
removed the casts from malloc() not needed and potentially dangerous.
changed the sizes to unsigned. A size can never be negative
diagnostic output should go to stderr.
a few of levels of indentation can be avoided by doing the error-case first, and returning early from the function on error.
I'm having problems with a segmentation fault on a Linux system.
I'm using code from Aho and Ullman's "Foundations of Computer Science" C edition.
This is the code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct que_element
{
long mem_address;
long mem_data;
int msg;
} Qq;
typedef struct CELL *LIST;
struct CELL
{
Qq el;
int element;
LIST next;
};
Qq l1element;
typedef struct
{
LIST front;
LIST rear;
} QUEUE;
main()
{
QUEUE *l1c2l1d; /*L1 Controller to L1 Data */
l1c2l1d->front = malloc(sizeof *l1c2l1d);
}
Is there an initializing step I'm missing?
Yes, l1c2l1d is uninitialized in your code. Dereferencing it means dereferencing NULL (since l1c2l1d is global). Try this:
l1c2l1d = malloc(sizeof *l1c2l1d);
l1c2l1d->front...
EDIT In light of last edit
You have this:
main()
{
QUEUE *l1c2l1d; /*L1 Controller to L1 Data */
l1c2l1d->front = malloc(sizeof *l1c2l1d);
}
In this case l1c2l1d is uninitialized, it points to garbage. Try this (copy-paste it this time):
main()
{
QUEUE *l1c2l1d; /*L1 Controller to L1 Data */
l1c2l1d = malloc(sizeof *l1c2l1d);
l1c2l1d->front = malloc(*l1c2l1d->front);
}
You seem to be going for something along the lines of:
main()
{
QUEUE l1c2l1d = { 0, 0 }; /*L1 Controller to L1 Data */
l1c2l1d->front = l1c2l1d->rear = malloc(sizeof CELL);
}