Structure Array as a parameter and it's member access - arrays

This code is written in C. The first line of Node_reset() function occurs an error. (Structure array is allocated dynamically in main function.) I think there's something wrong in member-access of Node_reset(), also Create() might occur same kind of error. Input.txt, the following format is provided:
2
3 dfs(3)
786 368 603
5 bfs(4)
825 162 768 724 635
The number in the first line (i.e., 2) shows the number of test cases to be processed. From the second line, test cases are given, and the information for each case is provided over two lines.
In the first line (line number 2 in the example above), the first number (i.e., 3) indicates the number of integers in that case, and the next string (i.e., dfs(3)) shows the location of the target number that you need to look for. In this example, the target number is on the third node of DFS.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_QUEUE_SIZE 100
#define FALSE 1;
#define TRUE 0;
typedef struct BST_node{
int data;
int visited;
struct BST_node * leftChild;
struct BST_node * rightChild;
}node;
typedef node* TreeNode;
typedef struct {
TreeNode data[MAX_QUEUE_SIZE];
int front;
int rear;
}Queue;
void Node_reset(TreeNode* input_tree, int BST_size)
{
for(int i=0;i<BST_size;i++)
{
input_tree[i]->data = 0; //"Thread 1: EXC_BAD_ACCESS (code=1, address=0x0)"occurs
input_tree[i]->leftChild=NULL;
input_tree[i]->rightChild=NULL;
input_tree[i]->visited=FALSE;
}
}
void Create(TreeNode* input_tree, int data[], int BST_size)
{
for(int i=0;i<BST_size;i++)
{
input_tree[i]->data=data[i];
}
for(int i=0;i<BST_size-1;i++)
{
if(input_tree[i]->data > input_tree[i+1]->data) input_tree[i]->leftChild=input_tree[i+1];
else input_tree[i]->rightChild=input_tree[i+1];
}
}
void init_Q(Queue* q)
{
q->front = q->rear =0;
}
int IsEmpty(Queue* q)
{
return (q->front == q->rear);
}
int IsFull(Queue* q)
{
return ((q->rear+1)%MAX_QUEUE_SIZE==q->front);
}
void enqueue(Queue* q,TreeNode data)
{
if(IsFull(q))
{
printf("Queue is Full");
}
q->rear = (q->rear+1)%MAX_QUEUE_SIZE;
q->data[q->rear]=data;
}
TreeNode dequeue(Queue* q)
{
if(IsEmpty(q))
{
printf("Queue is empty");
return NULL;
}
q->front = (q->front+1)%MAX_QUEUE_SIZE;
return q->data[q->front];
}
int DFS_search(TreeNode Node, int *searching_times)
{
while(*searching_times==0){
*searching_times--;
if(Node->leftChild!=NULL) DFS_search(Node->leftChild, searching_times);
if(Node->rightChild!=NULL) DFS_search(Node->rightChild, searching_times);
}
return Node->data;
}
int BFS_search(TreeNode* Node, int searching_times)
{
Queue q;
init_Q(&q);
for(int i=0;i<searching_times;i++)
{
enqueue(&q, Node[i]);
if(Node[i]->leftChild)
enqueue(&q, Node[i]->leftChild);
if(Node[i]->rightChild)
enqueue(&q, Node[i]->rightChild);
}
for(int i=0;i<searching_times;i++)
{
if(i==searching_times-1) return dequeue(&q)->data;
else dequeue(&q);
}
return 0;
}
void pass_result(int result_num,int *result,int result_arr[])
{
result_arr[result_num]=(*result);
}
void return_result(int result_arr[],int how_many)
{
FILE *of = fopen("output.txt","w");
for(int i=0;i<how_many;i++)
{
fprintf(of, "%d\n",result_arr[i]);
}
fclose(of);
}
int main()
{
int how_many_times; //the number of input expression
int BST_size; //input the number of element here
char string[7]={0}; //input string data here
char temp[2]={0}; //input searching num
int searching_times; //the number of input expression
int result; //result of expression
FILE *fp = fopen("input.txt","r");
fscanf(fp, "%d", &how_many_times);
int *result_arr=(int*)malloc(sizeof(int)*how_many_times);
for(int i=0;i<how_many_times;i++)
{
memset(string, 0, sizeof(char)*7); //reset string[]
memset(temp, 0, sizeof(char)*2); //reset temp[]
fscanf(fp, "%d", &BST_size); //pass BST size
int* input=(int*)malloc(sizeof(int)*BST_size); //allocate heep memory as long as input BST size
fscanf(fp, "%s", string); //pass string input data to string[]
TreeNode* tree=(TreeNode*)malloc(sizeof(TreeNode)*BST_size);
Node_reset(tree, BST_size);
for(int i=0;i<BST_size;i++) //input elements in array
{
fscanf(fp, "%d",&input[i]);
}
Create(tree, input, BST_size);
for(int i=0;i<2;i++)
{
temp[i]=string[i+4];
}
searching_times=atoi(temp); //input data about searching times becomes integer type
if(strcmp(&string[0],"d")) result=DFS_search(tree[0], &searching_times);
if(strcmp(&string[0],"b")) result=BFS_search(tree, searching_times);
pass_result(i, &result, result_arr); //pass the result
free(input);
}
return_result(result_arr, how_many_times); //return result in txt file
free(result_arr); //free result heep data
}
This is the part that occurs error. If needed please refer full code or tell me what I could do more. 😂
#define MAX_QUEUE_SIZE 100
#define FALSE 1;
#define TRUE 0;
typedef struct BST_node{
int data;
int visited;
struct BST_node * leftChild;
struct BST_node * rightChild;
}node;
typedef node* TreeNode;
typedef struct {
TreeNode data[MAX_QUEUE_SIZE];
int front;
int rear;
}Queue;
void Node_reset(TreeNode* input_tree, int BST_size)
{
for(int i=0;i<BST_size;i++)
{
input_tree[i]->data = 0;
input_tree[i]->leftChild=NULL;
input_tree[i]->rightChild=NULL;
input_tree[i]->visited=FALSE;
}
}
void Create(TreeNode* input_tree, int data[], int BST_size)
{
for(int i=0;i<BST_size;i++)
{
input_tree[i]->data=data[i];
}
for(int i=0;i<BST_size-1;i++)
{
if(input_tree[i]->data > input_tree[i+1]->data) input_tree[i]->leftChild=input_tree[i+1];
else input_tree[i]->rightChild=input_tree[i+1];
}
}
int main()
{
int how_many_times; //the number of input expression
int BST_size; //input the number of element here
char string[7]={0}; //input string data here
char temp[2]={0}; //input searching num
int searching_times; //the number of input expression
int result; //result of expression
FILE *fp = fopen("input.txt","r");
fscanf(fp, "%d", &how_many_times);
int *result_arr=(int*)malloc(sizeof(int)*how_many_times);
for(int i=0;i<how_many_times;i++)
{
fscanf(fp, "%d", &BST_size); //pass BST size
int* input=(int*)malloc(sizeof(int)*BST_size); //allocate heep memory as long as input BST size
fscanf(fp, "%s", string); //pass string input data to string[]
TreeNode* tree=(TreeNode*)malloc(sizeof(TreeNode)*BST_size);
Node_reset(tree, BST_size);
for(int i=0;i<BST_size;i++) //input elements in array
{
fscanf(fp, "%d",&input[i]);
}
Create(tree, input, BST_size);
}
}

Related

False value passed on binary tree adt lead to wrong output

So i try to make binary tree using array implementation. I just start it but I got a problem. First, this is my struct that I use to build my node for the tree
typedef char infotype;
typedef int letak; //it's the variable to tell the array position number
typedef struct simpul
{
infotype info;
letak parent;
letak rightSon, leftSon;
}elemenSimpul;
typedef struct
{
elemenSimpul treeMember[30]; //my tree have very maximum 30 nodes in it.
int maksimum; //it's the variable to put how many node the user wants and should be under 30
}tree;
here is my btreestatic.h
#ifndef btreestatic_H
#define btreestatic_H
void createTree(tree T);
void createNode(tree T, int i, char value);
void initNode(tree T, int i);
#endif
and for construct the tree I use these at my btreestatic.c
#ifndef btreestatic_C
#define btreestatic_C
#include <stdio.h>
#include <math.h>
#include "btreestatic.h"
void createTree(tree T)
{
T.treeMember[0].parent = -1;
}
void createNode(tree T,int i, char value)
{
int leftchild;
int rightchild;
T.treeMember[i].info = value;
leftchild = 2 * i + 1;
rightchild = 2 * i + 2;
if(leftchild < T.maksimum)
{
T.treeMember[i].leftSon = leftchild;
}
else
{
T.treeMember[i].leftSon = -1;
}
if (rightchild < T.maksimum)
{
T.treeMember[i].rightSon = rightchild;
}
else
{
T.treeMember[i].rightSon = -1;
}
if(i == 0)
{
T.treeMember[i].parent = -1;
}
else
{
T.treeMember[i].parent = (i - 1) / 2;
}
}
void initNode(tree T, int i)
{
char info;
printf("Input node info : ");
scanf(" %c", &info);
createNode(T, i, info);
}
#endif
and on my driver is
#include <stdio.h>
#include <stdlib.h>
#include "btreestatic.h"
int main()
{
tree A;
int maksimum;
int j;
createTree(A);
scanf("%d", &maksimum);
A.maksimum = maksimum;
for(j = 0; j < A.maksimum; j ++)
{
initNode(A, j);
}
printf("%c", A.treeMember[0].info);
return 0;
}
then I try my input as 3 (the maximum of the tree nodes are 3). First node(root) is 'a', second node is 'b', and third node is 'c'. But what i got on my screen is 'd' instead of 'a'. Can anyone tell me where did I go wrong? Thank you.

My application crashed without any error, problem with for loop(?)

My teacher gave me a library that describes a single linked list. I am writing a main file to test it, and i ran into a very weird problem.
This is the header for the linked list library (There are more function, but i only putin the one i used):
#ifndef DSSINGLYLINKEDLIST_H
#define DSSINGLYLINKEDLIST_H
#ifdef __cplusplus
extern "C" {
#endif
typedef struct _SListEntry SListEntry;
typedef struct _SListIterator SListIterator;
typedef void *SListValue;
/**
* Definition of a #ref SListIterator.
*/
struct _SListIterator {
SListEntry **prevNext;
SListEntry *current;
};
#define SLIST_NULL ((void *) 0)
typedef int (*SListCompareFunc)(SListValue value1, SListValue value2);
typedef int (*SListEqualFunc)(SListValue value1, SListValue value2);
SListEntry *slist_append(SListEntry **list, SListValue data);
SListValue slist_nthData(SListEntry *list, unsigned int n);
unsigned int slist_length(SListEntry *list);
#ifdef __cplusplus
}
#endif
#endif /* #ifndef DSSINGLYLINKEDLIST_H */
This is my .c file:
#include <stdlib.h>
#include <stdio.h>
#include "dssinglylinkedlist.h"
struct _SListEntry {
SListValue data;
SListEntry *next;
};
SListEntry *slist_append(SListEntry **list, SListValue data)
{
/* Create new list entry */
SListEntry *newEntry = malloc(sizeof(SListEntry));
if (newEntry == NULL) {
return NULL;
}
newEntry->data = data;
newEntry->next = NULL;
/* Hooking into the list is different if the list is empty */
SListEntry *rover;
if (*list == NULL) {
/* Create the start of the list */
*list = newEntry;
} else {
/* Find the end of list */
rover=*list;
while (rover->next != NULL) {
rover = rover->next;
}
/* Add to the end of list */
rover->next = newEntry;
}
return newEntry;
}
SListValue slist_nthData(SListEntry *list, unsigned int n)
{
/* Find the specified entry */
SListEntry *entry = slist_nthEntry(list, n);
/* If out of range, return NULL, otherwise return the data */
if (entry == NULL) {
return SLIST_NULL;
} else {
return entry->data;
}
}
unsigned int slist_length(SListEntry *list)
{
SListEntry *entry = list;
unsigned int length = 0;
while (entry != NULL) {
/* Count the number of entries */
++length;
entry = entry->next;
}
return length;
}
I think there's nothing wrong with these code.
I am writing a main using this library to store information of two polynomial:
#include <stdio.h>
#include <stdlib.h>
#include "dssinglylinkedlist.h"
void printPolynomial(SListEntry*);
int main()
{
SListEntry *poly1;
int n;
printf("Input n for poly1: ");
scanf("%d", &n);
printf("Input poly1: ");
for (int i=0; i<=n; i++) {
int *temp = (int *) malloc(sizeof (int));
scanf("%d", temp);
slist_append(&poly1, temp);
}
printPolynomial(poly1);
SListEntry *poly2;
printf("Input n for poly2: ");
scanf("%d", &n);
printf("Input poly2: ");
// for (int i=0; i<=n; i++) {
// int *temp = (int *) malloc(sizeof (int));
// scanf("%d", temp);
// slist_append(&poly2, temp);
// }
// printPolynomial(poly2);
return 0;
}
void printPolynomial(SListEntry *list)
{
int length = (int)slist_length(list);
for (int i = 0; i < length; i++) {
int temp = *((int *)slist_nthData(list,(unsigned int)i));
if (i >0 && temp >= 0) {
printf("+");
}
printf("%d*x^%d", temp, length-i-1);
}
printf("\n");
}
So if i comments the second loop (after i print 'Input poly2', like i wrote above), i can still input my poly1 and print it. But if i un-comments it, my program crashes immediately when i append the first element of poly1.
What is the problem of my code?

Traversing and printing a queue in C behaves differently when input is given by the user

I apologise if this concept has been explained on SOF before! I believe my case is slightly different and couldn't find a similar question in the website.
Here's the problem:
I'm trying to store char arrays (strings) in a Queue structure that I'm trying to implement.
The structure and its functions seem to work fine when I hardcode the data myself like this:
#include "Time.h"
#include <unistd.h>
int main(void){
struct Queue* q = CreateQueue();
Enqueue(q, "element1");
Enqueue(q, "element2");
Enqueue(q, "element3");
Enqueue(q, "element4");
PrintAll(q->first); // this outputs all elements and the time they've been in the queue.
return 0;
}
The output is as expected, a list of all 4 elements.
However, as soon as I put a simple menu together, to capture the data from the user instead of it being hardcoded as above, the PrintAll() function outputs a duplicate of the very last element enqueued. You also notice that I am timing each node to keep a track on when it was added to the queue and that seem to work fine. Although the ouput shows the last element entered duplicated N times (N being the size of the queue) the timer seems to show correctly for each node!
I am suspecting it's to do with the stdin stream that is not being cleaned but I thought I handled that with a block of code that is shown in main() function.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void){
char name[31];
char c;
int option;
int ch;
struct Queue* q = CreateQueue();
do
{
printf("\n 1. Add a an element to the queue");
printf("\n 2. Print all elements");
printf("\n 0. Exit");
printf("\n Please select an option");
while(scanf("%d", &option)!=1){
puts("Value non good");
ch=getchar();
while(ch!=EOF && ch!='\n'){
ch=getchar();
}
}
switch(option)
{
case 1:
{
ch=getchar();
while(ch!=EOF && ch!='\n')
{
ch=getchar();
}
printf("Please enter the name of the element.\n ");
fgets(name,30,stdin);
Enqueue(q, name);
PrintAll(q->first);
break;
}
case 2:
{
PrintAll(q->last);
break;
}
default:
return 0;
}
}while(option != 0);
return 0;
}
Can anybody please shed light on the problem ? I would appreciate it.
here's the rest of the code:
Time.c:
#include "Time.h"
struct Queue* CreateQueue()
{
struct Queue* q = malloc(sizeof(struct Queue));
q->first = NULL;
q->last = NULL;
q->size = 0;
return q;
}
void Enqueue(struct Queue* queue, char* string)
{
struct Node* newNode = malloc(sizeof(struct Node));
newNode->next = NULL;
newNode->student = string;
newNode->start_time = time(0);
if(queue->size == 0)
{
queue->first = newNode;
}
else
{
queue->last->next = newNode;
}
queue->last = newNode;
queue->size = queue->size + 1;
}
char* Dequeue(struct Queue* queue)
{
if (queue->size < 0)
{
exit(0);
}
char* toBeRemoved = queue->first->student;
struct Node* oldNode = queue->first;
queue->first = oldNode->next;
queue->size = queue->size - 1;
if(queue->size == 0)
{
queue->last = NULL;
}
free(oldNode);
return toBeRemoved;
}
int IsEmpty(struct Queue *q)
{
return q->size == 0;
}
char* Peek(struct Queue *q)
{
return q->first->student;
}
void PrintOne(struct Node *node)
{
if(node !=NULL)
{
int elapsed = ElapsedTime(node);
printTime(elapsed, node->student);
//printf("%s\n", node->student);
}
}
void PrintAll(struct Node* node)
{
if (node !=NULL)
{
PrintAll(node->next);
PrintOne(node);
}
}
// returns the waiting time for a student node.
int ElapsedTime(struct Node* node)
{
int elapsed;
time_t stop_time;
stop_time = time(NULL);
elapsed = difftime( stop_time , node->start_time );
return elapsed;
}
void printTime(int elapsed, char* student_name)
{
printf("%s : waiting for ", student_name);
int minutes_or_hours = 0; //Stores a zero to indicate that it is not neccesary to print minutes or hours.
//Stores a one to indicate that hours and/or minutes have been printed.
if( (elapsed / 3600) >= 1)
{
int hours = elapsed/3600;
if(hours == 1)
{
printf("1 hour, ");
}
else
{
printf("%d hours, ", hours);
}
elapsed = elapsed - (hours*3600);
minutes_or_hours = 1;
}
if( (elapsed / 60) >= 1)
{
int minutes = elapsed/60;
if(minutes == 1)
{
printf("1 minute, ");
}
else
{
printf("%d minutes, ", minutes);
}
minutes_or_hours = 1;
elapsed = elapsed - (minutes*60);
}
if(minutes_or_hours == 1)
{
printf("and ");
}
printf("%d seconds\n", elapsed);
}
Time.h:
#ifndef TIME_H_
#define TIME_H_
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
struct Node
{
time_t start_time;
struct Node* next;
char* student;
};
struct Queue
{
int size;
struct Node* first;
struct Node* last;
};
struct Queue* CreateQueue();
void Enqueue(struct Queue* , char* );
char* Dequeue(struct Queue* );
int IsEmpty(struct Queue *);
char* Peek(struct Queue *);
void PrintOne(struct Node *);
void PrintAll(struct Node *);
int ElapsedTime(struct Node* );
void printTime(int , char* );
#endif /* TIME_H_ */
In the function Enqueue() you have only copied the string pointer to your structure. In your first case that works, because all the four strings have different pointers to string literals. But in your second example, you are storing the pointer of your data entry name, and the contents of this string change with each entry. Each structure store the same pointer, so all point to the most recent string you typed in. If your struct stored the actual string, it would work (but you need to be careful with string lengths).
struct Node
{
time_t start_time;
struct Node* next;
char student[31];
};
void Enqueue(struct Queue* queue, char* string)
{
...
strncpy (newNode->student, 30, string);
...
}

finding a dangling pointer

I have a problem with my code. I am getting a segmentation fault error, which I understand is a dangling pointer problem(generally) or a faulty allocation of memory. The compiler dose not show at what line the problem might be, so my question is how do I detect these problems for further concern? and where would my problem be in the code?
here is my code:
`#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ARRAY_SIZE(a) sizeof(a)/sizeof(a[0])
#define ALPHABET_SIZE (256)
#define CHAR_TO_INDEX(c) ((int)c - (int)'a')
#define LEVELS 255
// trie node
struct n
{
char value,level,isLeaf;
struct n* children[ALPHABET_SIZE];
struct n* failLink;
};
typedef struct n node;
//trie
struct t
{
node *root;
int count;
};
typedef struct t trie;
void bytesCpy(char *to, char *from, int len)
{
int i;
for(i=0;i<len;i++)
{
to[i]=from[i];
}
}
// Returns new trie node (initialized to NULLs)
node *getNode(trie *t, char value,char level)
{
node *pNode = NULL;
pNode = (node *)malloc(sizeof(node));
if (pNode)
{
printf("ok\n");
int i;
for (i = 0; i < ALPHABET_SIZE; i++)
{
pNode->children[i] = NULL;
}
pNode->failLink = t->root;
pNode->value=value;
pNode->level=level;
pNode->isLeaf=0;
}
else
printf("error\n");
return pNode;
}
// Initializes trie (root is dummy node)
void initialize(trie *t)
{
t->root = getNode(t, '[', 0);
//t->count = 0;
}
// If not present, inserts key into trie
// If the key is prefix of trie node, just marks leaf node
void insert(trie *t, char key[], int len)
{
int level;
char value;
node *node = t->root;
for (level = 0; level<len; level++)
{
value = key[level];
printf("value: %c\n",value);
if (node->children[value] == NULL)
{
node->children[value] = getNode(t, value, level+1);
}
node = node->children[value];
}
node->isLeaf=1;
}
// Returns non zero, if key presents in trie
int search(trie *t, char key[])
{
int level;
int length = strlen(key);
int value;
node *node;
node = t->root;
for (level = 0; level < length; level++)
{
value = key[level];//CHAR_TO_INDEX(key[level]);
if (!node->children[value])
{
node = node->failLink;
return 0;
}
node = node->children[value];
}
return (0 != node);// && node->value);
}
void search1(trie *t, char *c, int len)
{
node *curNode = t->root;
int i;
for(i=0; i<=len; i++)
{
printf("i=%d curnode=%p\n",i,curNode);
if(curNode->isLeaf) //leaf: cuvant gasit
{
printf("if1 curGasit \n");
do{
curNode=curNode->failLink;
if(curNode->isLeaf)
printf("if1 curGasit \n");
else break;
}while(1);
continue;
}
else //nu e gasit inca
{
if(curNode->children[c[i]]==NULL) //fail
{
printf("if2\n");
curNode = curNode->failLink;
continue;
}
else //litera gasita: go on
{
printf("el2\n");
curNode=curNode->children[c[i]];
}
}
}
printf("end of search\n");
}
node* searchAux(trie *t, node *curRoot, char cuv[], char len, int level ,int failLevel)
{
char cuvAux[1024];
bytesCpy(cuvAux,cuv,len);
printf("searchAux level:%d cuvAux:%s curRootLevel:%d\n",level,cuvAux,curRoot->level);
if(cuvAux[level+1] == '\0') //got to the end of cuvAux
{
printf("1st if\n");
return curRoot;
}
if(curRoot->children[cuvAux[level+1]] == NULL) //fail: letter not found
{
printf("3rd if\n");
return searchAux(t, t->root, &cuvAux[failLevel+1], len, 0, failLevel+1);
}
else //letter found: go on
{
printf("3rd else\n");
if(cuvAux[level+2] == '\0') //the found letter was the last of the string
{
printf("4th if\n");
return curRoot->children[cuvAux[level+1]]; //return final pointer
}
else //the found letter was not the last of the string: continue with the next one
{
printf("4th else\n");
return searchAux(t, curRoot->children[cuvAux[level+1]], cuvAux, len, level+1, failLevel);
}
}
}
void createFailLinks(trie *t, node* curRoot, char cuv[], int level)
{
int i;
char cuvAux[1024];
bytesCpy(cuvAux,cuv,1024);
if(curRoot == NULL)
return;
for(i=0;i<ALPHABET_SIZE/*curRoot->children[i] != NULL*/;i++)
{
if(curRoot->children[i] == NULL)
continue;
else
{
cuvAux[level] = curRoot->children[i]->value;
printf("createFailLinks %c%d\n",cuvAux[level],curRoot->children[i]->level);
curRoot->children[i]->failLink = searchAux(t, t->root, cuvAux, level+1, 0, 0);
createFailLinks(t,curRoot->children[i],cuvAux,level+1);
}
}
printf("got\n");
}
void printTrie(node *curRoot)
{
int i;
if(curRoot == NULL)
return;
printf("%c: ", curRoot->value);
for(i=0;i<ALPHABET_SIZE;i++)
if(curRoot->children[i] != NULL)
{
printf("%c ", i);
}
printf("\n");
for(i=0;i<ALPHABET_SIZE;i++)
if(curRoot->children[i] != NULL)
{
printTrie(curRoot->children[i]);
}
}
void checkLinks(node* curRoot)
{
int i;
if(curRoot == NULL)
return;
printf("node %c%d: ",curRoot->value,curRoot->level);
for(i=0;i<256;i++)
if(curRoot->children[i] != NULL)
printf("\n\t%c%d:%c%d",curRoot->children[i]->value, curRoot->children[i]->level, curRoot->children[i]->failLink->value,curRoot->children[i]->failLink->level);
printf("\n");
for(i=0;i<256;i++)
if(curRoot->children[i] != NULL)
checkLinks(curRoot->children[i]);
}
int mai()
{
FILE *fd = fopen("VirusDatabase.txt","r");//O_RDONLY);
int i;
char c;
for(i=0;i<1000;i++)
{
fscanf(fd, "%c", &c);
printf("%c",c);
}
}
int main()
{
// Input keys (use only 'a' through 'z' and lower case)
char keys[][1024] = { "he", "she", "her", "his", "heres"};
char cuv[] = {'\0','\0','\0','\0','\0','\0'};
trie t;
char output[][32] = { "Not present in trie", "Present in trie" };
int i;
char text[]={"andreiherutshevlastashecristihiskatjaheres"};
initialize(&t);
// Construct trie
for (i = 0; i < ARRAY_SIZE(keys); i++)
{
insert(&t, keys[i], strlen(keys[i]));
}
createFailLinks(&t, t.root, cuv, 0);
printTrie(t.root);
printf("\n\n");
checkLinks(t.root);
search1(&t, text, strlen(text));
return 0;
// Search for different keys
printf("%s --- %s\n", "abcd", output[search(&t, "abcd")]);
printf("%s --- %s\n", "ab", output[search(&t, "ab")]);
printf("%s --- %s\n", "ccdd", output[search(&t, "ccdd")]);
printf("%s --- %s\n", "thaw", output[search(&t, "thaw")]);
return 0;
char a = getchar();
}`
Do you have access to a debugger? I ran your code in a debugger and get a memory access violation at line 157 here:
return searchAux(t, t->root, &cuvAux[failLevel+1], len, 0, failLevel+1);
You seem to be recursively calling searchAux. ie you have:
node* searchAux(trie *t, node *curRoot, char cuv[], char len, int level ,int failLevel)
{
char cuvAux[1024];
...
return searchAux(t, t->root, &cuvAux[failLevel+1], len, 0, failLevel+1);
...
Anyway, eventually the buffer size variable failLevel exceeds the size of your buffer so you are attempting to access memory outside the bounds of your array which is why you get an access violation.
The easiest way to debug is use an interactive debugger. On Windows there is a free version of Visual Studio with a very good debugger. On linux you can use GDB.
Failing that you can embed print statements to print out variables before the crash.
You can add print statements at lines of code.
#include <iostream>
std::cout << "At Line: " << __LINE__ << endl;
putting that at various lines of code, you can see what lines got executed, and find where it crashes.
This is for C++. My bad. Same idea, but put printf() statements and see where it stopped executing to narrow down the crash location.

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