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;
}
Related
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.
So I'm trying to get input from user and store it in linked list, using array (every 5 chars a new linked list is created). After getting EOF I want to print the input (actually print the arrays in each linked list)
here is my code:
#include <stdio.h>
#include <stdlib.h>
#define MAX 5
typedef struct charNode {
int arr[MAX];
struct charNode *next;
} charNode;
void addNode();
void printAll();
int main(){
int c,i;
charNode *head=malloc(sizeof(charNode));
charNode *current=head;
while((c=getchar())!=EOF){
while(i<MAX){
current->arr[i++]=c;
}
i=0;
addNode(current);
}
printAll(head);
return 0;
}
void addNode(charNode *current){
struct charNode *link = (struct charNode*) malloc(sizeof(struct charNode));
current->next =link;
link->next = NULL;
current=current->next;
}
void printAll(charNode *head){
int j=0;
while(head->next!=NULL){
while(j<MAX){
printf("\n %d \t",head->arr[j++]);
}
printAll(head->next);
}
return;
}
and I'm getting "Segmentation fault (core dumped)" error..
This is Undefined behavior:
int c,i;
charNode *head=malloc(sizeof(charNode));
charNode *current=head;
while((c=getchar())!=EOF){
while(i<MAX){
current->arr[i++]=c;
}
since you are using i uninitialized to access your array, which could produce the Segmentation fault.
Change this:
printf("\n %d \t",head->arr[j++]);
to this:
printf("\n %c \t",head->arr[j++]);
so that you print characters, instead of numbers.
Simply initialize i to 0 for a start, happy debugging! =)
int main(){
char c;
charNode *head=malloc(sizeof(charNode));
charNode *current=head;
int i = 0;
while((c=getchar())!=EOF){
getchar();
while(i<MAX){
current->arr[i++]=c;
}
i=0;
addNode(¤t);
}
printAll(head);
return 0;
}
void addNode(charNode **current){
struct charNode *link = malloc(sizeof(struct charNode));
link->next = NULL;
(*current)->next =link;
*current=(*current)->next;
}
void printAll(charNode *head){
int j=0;
if(head!=NULL){
while(j<MAX){
printf("%c\n",head->arr[j++]);
}
if(head->next != NULL)
printAll(head->next);
}
}
I changed your code a bit. Especially take a good look at addNode(). Now it works correctly
I have to make a list that arrange the people in decreasing order of their number('no' for my program). I tryed to make it by modifying the addNode function but I got no result(peoples do not arrange by their number). This is my code:
Header code:
#ifndef __EX__
#define __EX__
typedef struct Person{
char name[10];
float no;
struct Person *pNext;
} NODE, *pNODE, **ppNODE;
void addNode(ppNODE, pNODE);
void travers(pNODE, unsigned int*);
#endif
Functions folder:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <math.h>
#include <string.h>
#include "EX.h"
void addNode (ppNODE ppPrim, pNODE p){
pNODE q = (pNODE)malloc(sizeof(NODE));
assert(q!=NULL);
printf("Add name: \n");
scanf("%s", &q->name);
printf("\nAdd no: ");
scanf("%f", &q->no);
if (p == NULL || q->no < p->no) {
q->pNext = *ppPrim;
*ppPrim = q;
} else {
q->pNext = p->pNext;
p->pNext = q;
}
return;
}
void travers(pNODE pPrim, unsigned int *pLen){
*pLen = 0;
pNODE tmp = pPrim;
while (tmp != NULL){
puts (tmp->name);
fprintf(stdout, " no %.2f\n", tmp->no);
tmp = tmp->pNext;
(*pLen)++;
}
return;
}
Main folder:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <math.h>
#include <string.h>
#include "EX.h"
int main(){
unsigned int len;
pNODE prim = NULL;
int i;
for (i=0; i<=1; i++){
addNode(&prim, prim);
addNode(&prim, prim->pNext);
}
travers(prim, &len);
return 0;
}
When you insert a new node to the list, you must traverse the list until you find a suitable place to insert it. Your code takes a second argument, which isn't really needed and causes confusion, and only looks at that.
The code to insert a code q at the end of a list that is defined by its head is:
Node *prev = NULL;
Node *p = *head;
while (p) {
prev = p;
p = p->pNext;
}
q->pNext = p;
if (prev == NULL) {
*head = q;
} else {
prev->pNext = q;
}
You can get rid of keeping track of the previous node and the distinction between inserting at the head and inserting after that by traversing the list with a pointer to node pointer:
Node **p = &head;
while (*p && (*p)->no < q->no) {
p = &(*p)->pNext;
}
q->pNext = *p;
*p = q;
In this concise code, p holds the address of the head at first and the address of the pNext pointer of the previous node. Both can be updated via *p.
You can now use this code to traverse only as far as the numbers associated with each node are smaller than the one of the node to insert. here's a complete program:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef struct Node Node;
void addNode(Node **p, const char *name, float no);
void travers(Node *pPrim, unsigned int *pLen);
struct Node {
char name[10];
float no;
Node *pNext;
};
void addNode(Node **p, const char *name, float no)
{
Node *q = malloc(sizeof(*q));
assert(q != NULL);
snprintf(q->name, sizeof(q->name), "%s", name);
q->no = no;
while (*p && (*p)->no < q->no) {
p = &(*p)->pNext;
}
q->pNext = *p;
*p = q;
}
void traverse(const Node *pPrim, unsigned int *pLen)
{
*pLen = 0;
while (pPrim != NULL) {
fprintf(stdout, "%-12s%.2f\n", pPrim->name, pPrim->no);
pPrim = pPrim->pNext;
(*pLen)++;
}
}
int main()
{
unsigned int len;
Node *prim = NULL;
addNode(&prim, "Alice", 0.23);
addNode(&prim, "Bob", 0.08);
addNode(&prim, "Charlie", 0.64);
addNode(&prim, "Dora", 0.82);
traverse(prim, &len);
printf("\n%u entries.\n", len);
return 0;
}
Things to node:
I've used Node * and Node ** instead of the typedeffed pNODE and ppNODE. In my opinion using the C pointer syntax is clearer.
You should separate taking user input from adding a node.
In your code you shouldn't pass the address of the char array when scanning a string, just the char array. (It happens to work, but it isn't correct. The compiler should warn you about that.)
This code is about binary tree.
It can work well.
But after I press the enter key and get the correct answer,it turns out stopping working.WHY?
This is the answer
source code:
#include <stdio.h>
#include <stdlib.h>
typedef struct BiTNode
{
char data;
struct BiTNode* rchild;
struct BiTNode* lchild;
}BiTNode;
typedef BiTNode* BiTree;
int CreateBiTree(BiTree *T);
void Visit(BiTree T);
void PreOrder(BiTree T);
void InOrder(BiTree T);
void PostOrder(BiTree T);
int main(void)
{
BiTree T;
CreateBiTree(&T);
PreOrder(T);
return 0;
}
int CreateBiTree(BiTree *T)
{
char data;
scanf("%c",&data);
if(data=='#')
{
*T==NULL;
}
else
{
*T=(BiTree)malloc(sizeof(BiTNode));
(*T)->data=data;
CreateBiTree(&(*T)->lchild);
CreateBiTree(&(*T)->rchild);
}
return 0;
}
void Visit(BiTree T)
{
printf("%c",T);
}
void PreOrder(BiTree T)
{
if(T!=NULL)
{
Visit(T);
PreOrder(T->lchild);
PreOrder(T->rchild);
}
}
In your Code you have many issues :-
In CreateBiTree(BiTree *T) function, you only modified single pointer for root, rchild and lchild. you should define Bitree *T locally in this function.
what is *T==NULL? Are you initializing or comparing?
scanf("%c",&data); this statement will also create a problem in character case. this statement will wait for '\n' also. so you should write scanf(" %c",&data).
*T=(BiTree)malloc(sizeof(BiTNode)); this statement is also wrong, malloc return pointer, so you should do correct type casting. *T=(BiTree *)malloc(sizeof(BiTNode));
i have modified you source code for your reference, have look
//it can work
#include<stdio.h>
#include<stdlib.h>
using namespace std;
typedef struct BiTNode
{
char data;
struct BiTNode* rchild;
struct BiTNode* lchild;
}BiTNode;
typedef BiTNode BiTree;
BiTree *CreateBiTree();
void Visit(BiTree **T);
void PreOrder(BiTree *T);
void InOrder(BiTree T);
void PostOrder(BiTree T);
int main(void)
{
BiTree *T;
T=CreateBiTree();
PreOrder(T);
return 0;
}
BiTree *CreateBiTree()
{
BiTree *T;
char data;
scanf(" %c",&data);
printf("............%c\n",data);
if(data=='#')
return NULL;
T=(BiTree *)malloc(sizeof(BiTree));
T->data=data;
printf("Enter left child of %c:\n",data);
T->lchild=CreateBiTree();
printf("Enter right child of %c:\n",data);
T->rchild=CreateBiTree();
return T;
}
void Visit(BiTree **T)
{
printf("%c",(*T)->data);
}
void PreOrder(BiTree *T)
{
if(T!=NULL)
{
Visit(&T);
PreOrder(T->lchild);
PreOrder(T->rchild);
}
}
I have the following C program:
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
typedef struct node_t node_t;
struct node_t
{
char *name;
node_t **nodes;
};
node_t* init(int p_n)
{
node_t *node = malloc(sizeof(node_t));
node->name = "_ROOT_";
if(p_n > 0 && p_n < 10)
{
node->nodes = malloc(p_n*sizeof(node_t**));
char nbuffer[9];
int i;
for(i = 0; i < p_n; i++)
{
node_t *child = malloc(sizeof(node_t));
sprintf(nbuffer, "NAME %d", i);
child->name = nbuffer;
node->nodes[i] = child;
}
}
return node;
}
int main(int argc, char *argv[])
{
int n = 3;
node_t *ROOT = init(n);
printf("%sNODE {name:%s [%lu]}\n",
"", ROOT->name, sizeof(ROOT->nodes)/sizeof(ROOT->nodes[0])
);
assert(n == sizeof(ROOT->nodes)/sizeof(ROOT->nodes[0]));
free(ROOT);
return 0;
}
The assertion from the beginning of the main method fails and this is my problem. What I am doing wrong in the evaluation of the length of member nodes?
This post is know by me but from some reason it doesn't work for me. Why?
SK
Assuming a 32 bit pointer.
The sizeof(ROOT->nodes) is going to be 4 bytes. A pointer to a pointer it still a pointer.
The sizeof(ROOT->nodes[0]) is also going to be 4 bytes. It too is a pointer.
Hence 4/4 != 3 and your assert fails.
I'm not sure what your objective is, but if you're wanting to do something like this with dynamically allocated storage you might do something like the following. It can be extended with additional APIs to add, remove, etc. This solution maintains a count of the number of elements in the list.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#define NAME_SIZE 32
typedef struct node_s {
char *name;
} node_t;
typedef struct node_list_s {
int count;
node_t *nodes;
} node_list_t;
void init(node_list_t *l, int p_n) {
int i = 0;
char name[NAME_SIZE];
if(!l) return;
memset(l, 0, sizeof(node_list_t));
l->nodes = malloc(p_n*sizeof(node_t));
l->count = p_n;
for(i=0;i<l->count;i++) {
snprintf(name,sizeof(name),"NAME %d",i);
l->nodes[i].name = strdup(name);
}
}
void term(node_list_t *l) {
int i = 0;
if(!l) return;
for(i=0;i<l->count;i++) {
if(l->nodes[i].name) free(l->nodes[i].name);
}
if(l->nodes) free(l->nodes);
}
void print(node_list_t *l) {
int i = 0;
if(!l) return;
for(i=0;i<l->count;i++) {
printf("%d %s\n", i, l->nodes[i].name ? l->nodes[i].name : "empty" );
}
}
int main(int argc, char *argv[]) {
node_list_t list;
init(&list, 3);
print(&list);
term(&list);
return 0;
}