Segmentation fault when trying to print out a struct - c

I'm trying to make a code that will allow the user to input any amount of entries he wants, and then print them out (and other functions, still have to get to that). But when I try to launch the code it allows me to input the entries, but when I want to print them out, it doesn't register current.name or current.telNo (only prints out 1: has tel. No. ) and a segmentation error follows after it. Any idea how I can fix that.
#include <stdio.h>
#include <stdlib.h>
int listSize;
int counter = 0;
struct Entry {
char name[20];
char telNo[9];
struct Entry *next;
} current;
int main()
{
struct Entry *linkedList = (struct Entry * )malloc(sizeof(struct Entry));
struct Entry *current = linkedList;
first(current);
print(current);
return 0;
}
void first(struct Entry linkedList)
{
int i;
printf("enter list size: ");
scanf("%d", &listSize);
printf("Now enter entries one by one: \n");
for (i = 0; i < listSize; i++) {
counter++;
printf("Name: ");
scanf("%s", linkedList.name);
printf("Telephone: ");
scanf("%s", linkedList.telNo);
if (i != listSize -1) {
linkedList.next = (struct Entry *)malloc(sizeof(struct Entry));
linkedList = *linkedList.next;
} else {
linkedList.next = NULL;
}
}
}
void print(struct Entry linkedList)
{
int nr = 1;
printf("\nTelephone book is:\n");
while (current.name != NULL) {
printf("%d: %s has tel. No.\t%s\n", nr, current.name, current.telNo);
current = *current.next;
nr++;
}
}

Instead of . you should have used -> and in your print() you were traversing current instead of linkedList which was causing the issue. Also your functions definitions should come before its usage. Please check the below snippet, i have made the corresponding changes.
#include <stdio.h>
#include <stdlib.h>
int listSize;
int counter = 0;
struct Entry {
char name[20];
char telNo[9];
struct Entry *next;
} current;
void print(struct Entry *linkedList)
{
int nr = 1;
printf("\nTelephone book is:\n");
while (linkedList->name != NULL) {
printf("%d: %s has tel. No.\t%s\n", nr, linkedList->name, linkedList->telNo);
linkedList = linkedList->next;
nr++;
}
}
void first(struct Entry *linkedList)
{
int i;
printf("enter list size: ");
scanf("%d", &listSize);
printf("Now enter entries one by one: \n");
for (i = 0; i < listSize; i++) {
counter++;
printf("Name: ");
scanf("%s", linkedList->name);
printf("Telephone: ");
scanf("%s", linkedList->telNo);
if (i != listSize -1) {
linkedList->next = (struct Entry *)malloc(sizeof(struct Entry));
linkedList = linkedList->next;
} else {
linkedList->next = NULL;
}
}
}
int main()
{
struct Entry *linkedList = (struct Entry * )malloc(sizeof(struct Entry));
struct Entry *current = linkedList;
first(current);
print(current);
return 0;
}

while (current.name != NULL)
should be
while (current != NULL)
otherwise current = *current.next will become NULL and crash on the while condition

current.name is a pointer to reserved 20-byte area, which is always non-NULL.
I would initialize *next with NULL every time I allocate it (there are few ways to do that, easiest: assign NULL to it right after malloc). And do the check like that: if (current.next != NULL).
You also can check for current.name[0] != 0, but the first option is cleaner.

There are a number of errors in your code but, essentially two main 'points of confusion':
First, you seem to be confusing a structure (struct Entry) with a pointer-to-structure (as in, for example, struct Entry *next;).
Second, you have two different variables called current - one defined globally (which is the only one that is 'visible' to your print function), and another one defined locally inside main (this one will 'hide' the former).
Here is a corrected version of your code, with triple-slash (///) comments wherever I've made changes. Feel free to ask for further clarification and/or explanation.
#include <stdio.h>
#include <stdlib.h>
int listSize;
int counter = 0;
struct Entry {
char name[20];
char telNo[9];
struct Entry* next;
} *current; /// Here, we define a GLOBAL variable, "current" that is a POINTER to the struct
void first(struct Entry* linkedList); /// Put "Function Prototypes* here, so that "main" knows what they are
void print(struct Entry* linkedList); /// You need to pass POINTERS to structures, not the actual structures
int main()
{
struct Entry* linkedList = (struct Entry*)malloc(sizeof(struct Entry));
// struct Entry* current = linkedList; /// This declaration 'hides' the global variable
current = linkedList; /// Here, we (properly) assign the global pointer's value
first(current);
print(current);
return 0;
}
void first(struct Entry* linkedList) /// Pointer (see above)
{
int i;
printf("enter list size: ");
scanf("%d", &listSize);
printf("Now enter entries one by one: \n");
for (i = 0; i < listSize; i++) {
counter++;
printf("Name: ");
scanf("%s", linkedList->name); /// Use "->" instead of "." to get a pointer's member (and elsewhere)
printf("Telephone: ");
scanf("%s", linkedList->telNo); /// See above
if (i != listSize - 1) {
linkedList->next = (struct Entry*)malloc(sizeof(struct Entry)); /// See above
linkedList = linkedList->next; /// Again - changed here to use pointers!
}
else {
linkedList->next = NULL; /// See above
}
}
}
void print(struct Entry* linkedList) /// Pointer (see above)
{
int nr = 1;
printf("\nTelephone book is:\n");
while (current != NULL) { /// You need to check if "current" is not NULL before trying to access any of its members...
// while (current.name != NULL) {
printf("%d: %s has tel. No.\t%s\n", nr, current->name, current->telNo); /// Same "." to "->" changes as before
current = current->next; /// And again!
nr++;
}
}
There are other ways to 'fix' your code (and also improve it): for example, you never use the argument you pass to print, relying instead on the 'global' variable I mentioned earlier.

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.

Graph representation with dynamic linked lists

I start by saying I am quite new to C and right now, I struggle with some very non intuitive mistakes. I've tried for quite a while now to reach at some solution, but I am always reaching a dead end.
I am trying to build a couple of functions for inserting and displaying a graph via dynamic linked lists. At compile time everything works just fine, but the elements seem not to be well displayed. Actually, just like in the image below, only the first element of the node is displayed.
So the question is what is causing these errors and warnings and what should I do to remove them?
If you take a look at the code below, you will see that it has a few warnings(I don't know why they appear - I am using Code Blocks in Ubuntu with the GNU compiler) and also problems at displaying the elements of the graph. The problem lies most likely in the display_graph function, but I can't realize where.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct AdjListNode {
int dest;
struct LIST_NODE *next;
} LIST_NODE;
typedef struct AdjList {
struct LIST_NODE *head;
} ADJACENCY_LIST;
LIST_NODE *create_node(int dest) {
LIST_NODE *nod;
if(dest<0) exit(0);
nod = (LIST_NODE*)malloc(sizeof(LIST_NODE));
if(nod==NULL) {
printf("Problems at memory allocation!");
exit(0);
}
nod->dest = dest;
nod->next = NULL;
return (LIST_NODE*)nod;
}
void display_graph(ADJACENCY_LIST *v) {
int s, i;
LIST_NODE *nod;
s = sizeof(v);
for(i=0;i<=s;i++) {
nod = v[i].head;
//citeste lista cu head in primul nod
while(nod!=NULL) {
printf("Data from node: %d \n", nod->dest);
nod = nod->next;
}
}
}
int main()
{
int n; //number of graph nodes
int i; //just a counter
int dest; dest = -1; //it's actually the "name" of the nodes. They must all be positive so I started negative
char c;
ADJACENCY_LIST *t;
printf("The number of nodes of the graph: ");
scanf("%d", &n);
t = (ADJACENCY_LIST*)malloc(n*sizeof(ADJACENCY_LIST));
/* We make a loop for the nodes and each node has a while thru which I make the links */
for(i=0;i<n;i++) {
c = 'D'; // Initializing
printf("Specify the links of the node %d with the others:\n", i);
int contor; contor = 0;
while(c=='D') {
LIST_NODE *nod;
printf("The link with node: ");
scanf("%d%*c", &dest);
if(dest>=0){
nod = create_node(dest);
if(contor==0) t[i].head = (LIST_NODE*)nod; // just make the first node a head node
} else nod = NULL;
//verificam daca vrem sa continuam
printf("Do you want to link any other node to %d?(D to add, anything else STOP\n)", i);
c = getchar();
contor++; //increment counter
}
// inchidem lista
}
display_graph(t);
return 0;
}
Any help will be greatly appreciated!
EDIT:
As Christhofe(confirmed the problem) and Abhishek Vasisht pointed out the size of the vector v returned actually the size of the pointer.
But, there are still some warnings which I don't know why they still appear...all are
||=== Build: Debug in Grafuri1 (compiler: GNU GCC Compiler) ===|
/home/marianpc/Anul_1/SDA/Grafuri1/main.c||In function ‘display_graph’:|
/home/marianpc/Anul_1/SDA/Grafuri1/main.c|33|warning: assignment from incompatible pointer type|
/home/marianpc/Anul_1/SDA/Grafuri1/main.c|38|warning: assignment from incompatible pointer type|
/home/marianpc/Anul_1/SDA/Grafuri1/main.c|28|warning: unused variable ‘s’ [-Wunused-variable]|
/home/marianpc/Anul_1/SDA/Grafuri1/main.c||In function ‘main’:|
/home/marianpc/Anul_1/SDA/Grafuri1/main.c|71|warning: assignment from incompatible pointer type|
/home/marianpc/Anul_1/SDA/Grafuri1/main.c|76|warning: assignment from incompatible pointer type|
||=== Build finished: 0 error(s), 5 warning(s) (0 minute(s), 0 second(s)) ===|
The main thing is the program is functional now. Thanks a lot guys! Really helpful!!
Try this
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct AdjListNode {
int dest;
struct LIST_NODE *next;
} LIST_NODE;
typedef struct AdjList {
struct LIST_NODE *head;
} ADJACENCY_LIST;
LIST_NODE *create_node(int dest) {
LIST_NODE *nod;
if (dest < 0) exit(0);
nod = (LIST_NODE*)malloc(sizeof(LIST_NODE));
if (nod == NULL) {
printf("Problems at memory allocation!");
exit(0);
}
nod->dest = dest;
nod->next = NULL;
return (LIST_NODE*)nod;
}
void display_graph(ADJACENCY_LIST *v,int values) {
int s, i;
LIST_NODE *nod;
for (i = 0; i < values; ++i)
{
nod = v[i].head;
printf("Data from node: %d \n", i);
while (nod != NULL)
{
printf("Data : %d \n", nod->dest);
nod = nod->next;
}
}
}
int main()
{
int n; //number of graph nodes
int i; //just a counter
int dest; dest = -1; //it's actually the "name" of the nodes. They must all be positive so I started negative
char* c = (char*)(malloc(sizeof(char)));
ADJACENCY_LIST *t;
LIST_NODE *last_added;
printf("The number of nodes of the graph: ");
scanf("%d", &n);
t = (ADJACENCY_LIST*)calloc(n,sizeof(ADJACENCY_LIST));
/* We make a loop for the nodes and each node has a while thru which I make the links */
for (i = 0; i < n; i++) {
//c = 'D'; // Initializing
printf("Specify the links of the node %d with the others:\n", i);
int contor; contor = 0;
do {
LIST_NODE *nod;
printf("The link with node: ");
scanf("%d", &dest);
if (dest >= 0) {
nod = create_node(dest);
if (contor == 0)
{
t[i].head = (LIST_NODE*)nod; // just make the first node a head node
last_added = nod;
}
else
{
last_added->next = nod;
last_added = nod;
}
}
//verificam daca vrem sa continuam
printf("Do you want to link any other node to %d?(D to add, anything else STOP\n)", i);
fflush(stdin);
*c = getchar();
contor++; //increment counter
} while (*c == 'D');
}
display_graph(t,n);
return 0;
}
the following code compiles cleanly, works.
It does not have the capability of having a list of nodes for each entry in the first level list of pointers.
You can easily add that feature.
You also need to add the feature of passing each malloc'd node to free()
especially when an error has occurred
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct AdjListNode
{
int dest;
struct AdjListNode *next;
} ;
// declare list of pointers to nodes
static struct AdjListNode **head = NULL;
struct AdjListNode *create_node(int dest)
{
struct AdjListNode *nod;
nod = malloc(sizeof(struct AdjListNode));
if(nod==NULL)
{
perror(" malloc failed" );
printf("Problems at memory allocation!");
exit(-1);
}
// implied else, malloc successful
nod->dest = dest;
nod->next = NULL;
return nod;
} // end function: create_node
int main( void )
{
int n; //number of graph nodes
int i; //just a counter
int dest = -1; //it's actually the "name" of the nodes. They must all be positive so I started negative
printf("The number of nodes of the graph: ");
if( 1 != scanf("%d", &n) )
{ // then scanf failed
perror( "scanf for number of nodes failed" );
exit( -1 );
}
// implied else, scanf successful
// set ptr to list of node pointers
head = malloc(n*sizeof(struct AdjList*));
if( NULL == head )
{ // then malloc failed
perror( "malloc failed for list of pointers to nodes" );
exit( -1 );
}
// implied else, malloc successful
// initialize list of pointers (makes for easier cleanup, especially when a failure occurs
memset( head, 0x00, n*sizeof(struct AdjList*) );
/* We make a loop for the nodes and each node has a while thru which I make the links */
for(i=0;i<n;i++)
{
printf("Enter Dest value for %d of %d:", i, n);
if( 1 != scanf("%d", &dest) ) // note %d will skip over leading white space like newlines
{ // then scanf failed
perror( "scanf for dest value failed" );
exit(-1);
}
// implied else, scanf successful
if(dest>=0)
{
head[i] = create_node(dest);
}
else
{
printf( "Dest value must be >= 0\n" );
}
//verificam daca vrem sa continuam
// inchidem lista
} // end for
return 0;
} // end function: main

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.

How to write/read data to/from structure array using write/fread?

I have spent quite a lot time attempting to find a solution how to write and read structure to/from file and completely get stuck.
The code should be very simple, but I think I've missed quite important details about fwrite/fread. I think write is working but I am not completely sure. Once I try to read into array I get segmentation fault error on the k=1.
I would be ultimately happy if someone could guide me in what direction should I move further.
#include <stdio.h>
struct Student {
char matrikl[6];
char shortName[6];
int value1;
int value2;
int value3;
int value4;
int money;
}xStudent;
int calcMoney(int,int,int,int);
int main(void)
{
int i=0;
printf("How much students to insert!\n");
scanf("%i",&i);
struct Student S[i];
for (int var = 0; var < i; ++var) {
printf("insert student data\n");
printf("Matriklinumber\n");
scanf("%s", S[var].matrikl);
printf("Student name\n");
scanf("%s", S[var].shortName);
printf("Insert values!\n");
scanf("%i%i%i%i",&S[var].value1,&S[var].value2,&S[var].value3,&S[var].value4);
S[var].money=calcMoney(S[var].value1,S[var].value2,S[var].value3,S[var].value4);;
}
FILE*sourcefile;
sourcefile=fopen("text.txt","ab+");
for (int var = 0; var < i; ++var) {
fwrite(&S[var],sizeof(struct Student),1,sourcefile);
}
fclose(sourcefile);
sourcefile=fopen("text.txt","rb+");
struct Student A[i];
if (sourcefile==NULL) perror ("Error opening file");
else
{
int k=0;
while (fgetc(sourcefile) != EOF) {
fread(&A[k],sizeof(struct Student),1,sourcefile);
k++;
}
}
fclose(sourcefile);
return 0;
}
int calcMoney(int xvalue1, int xvalue2, int xvalue3, int xvalue4)
{
int Sum = xvalue1+xvalue2+xvalue3+xvalue4;
if(Sum==20)
return 100;
else
if(Sum>=16 && Sum<20)
return 75;
else return 0;
}
You have the right idea, but this should fix your problem.
for (int var = 0; var < i; ++var) {
fwrite(&S[i], sizeof(struct Student), 1, sourcefile);
}
The argument 1 in fwrite after the sizeof statement indicates you only want to add one Student at a time.
Please see the doc for fwrite: http://www.cplusplus.com/reference/cstdio/fwrite/
And also:
while (fgetc(sourcefile) != EOF) {
fread(&A[k], sizeof(struct Student), 1, sourcefile);
k++;
}
Please see the doc for fread: http://www.cplusplus.com/reference/cstdio/fread/
I know it's the cplusplus website, but it's the only place I could find good docs on the functions.
Also, the below array initializes to 0 elements:
struct Student A[k];
You may want to try managing a linked list for this instead.
Might end up looking something like:
struct StudentList {
struct Student* student;
struct StudentList* next;
};
struct StudentList* students = NULL;
while(!feof(sourcefile)) {
struct StudentList* newlink = malloc(sizeof(struct StudentList));
newlink->student = malloc(sizeof(struct Student));
newlink->next = NULL;
fread(newlink->student, sizeof(struct Student), 1, sourcefile);
if(NULL != students) {
struct StudentList* iter;
for(iter=students;
NULL != iter->next;
iter = iter->next); // iterate to last link
iter->next = newlink; // add new link to the end
} else students = newlink; // add new link to the beginning
}
Then to free your list, just use something like:
struct StudentList* iter, *head;
for(iter=students;
NULL != iter;)
{
head = iter;
free(iter->student);
free(iter);
iter = head;
}
the error is in the declaration of array A.
struct Student A[k];
k=0; so you are getting error since A[1] or so the array is not defined.
change the declaration to
struct Student A[i];
then it should run if rest of code and syntax is fine.
Fix fwrite line to:
fwrite(&S[i], sizeof(struct Student), 1, sourcefile);

hash table - linked lists - segmentation fault

I am trying to implement a hash table with linked list chaining. The following code below works -
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define TABSIZ 200
struct record {
struct record *next;
char name[BUFSIZ];
int data;
};
static struct record *htable[TABSIZ];
unsigned hash(char *s)
{
unsigned h;
for (h = 0; *s; s++)
h = *s;
//printf("%d", h%TABSIZ);
//I know its not a good hash function but i wanted to check chaining
return h % TABSIZ;
}
struct record *find(char *name)
{
struct record *item;
for (item = htable[hash(name)]; item; item = item->next)
{
if (strcmp(name, item->name) == 0)
return item;
}
return NULL;
}
struct record *insert(char *name,int value)
{
struct record *item;
unsigned h;
if ((item = find(name)) == NULL)
{
if ((item = malloc(sizeof (*item))) == NULL)
return NULL;
strcpy(item->name, name);
item->data=value;
h = hash(name);
item->next = htable[h];
htable[h] = item;
}
return item;
}
void printTable()
{
int i=0;
struct record *temp;
for(i=0;i<=TABSIZ;i++)
{
temp=htable[i];
while(temp!=NULL)
{
printf("\n%d - %s - %d\n", i,temp->name, temp->data);
temp=temp->next;
}
}
}
int main(void)
{
char buf[BUFSIZ];int value;
struct record *item;
do{
printf("Enter the name of the student:\n");
scanf("%s", buf);
if(strcmp(buf,"stop")==0) break;
printf("Enter the marks of the student:\n");
scanf("%d", &value);
if(insert(buf, value)==NULL)
{
break;
}
}while((strcmp(buf,"stop"))!=0);
printf("Enter a name to find: ");
scanf("%s", buf);
if((item=find(buf))!=NULL)
printf("The marks of the student is %d\n", item->data);
else printf("\n Not Found\n");
printTable();
return 0;
}
Now I am trying to remove the global variable and use local variable for the array of structures. I removed the global declaration of htable and declared it in main as
struct record *htable[TABSIZ];
and changed the functions to
struct record *find(struct record *htable, char *name);
struct record *insert(struct record *htable, char *name,int value);
and I'm calling the functions as
find(htable, name);
insert(htable,name,value);
but now my program is segfaulting. Am i passing the array of structures right? and have I declared it correctly. Any help would be greatly appreciated.
I was going down the wrong path with my earlier answer.
When it's a global, it's automatically initialized to 0.
When it's declared on the stack of main, it's not initialized.
Add a memset( htable, 0, sizeof(htable)) in main(), and that should return it to the previous behavior.
In printTable():
for(i=0;i<=TABSIZ;i++)
looks suspect. You prabably want:
void printTable()
{
unsigned int i;
struct record *temp;
for(i=0; i < TABSIZ;i++)
{
for (temp=htable[i]; temp!=NULL; temp=temp->next )
{
printf("\n%d - %s - %d\n", i,temp->name, temp->data);
}
}
}

Resources