Very weird issue - C & pthreads - c

I'm having a very strange problem with this bit of code, sorry its pretty messy. Basically its a pagerank algorithm. Each struct webpage is contained in the dynamic array "pages". The pages vector is put through the algorithm until its absolute value (|P|) is smaller than 'epsilon'. Now the issue is with lines 195-201. If i remove the iteration over the array in those lines (i.e. an empty while loop), it works for cases that only require one iteration. However, when i do have the for loop (even for one iteration cases), it throws error6 (line 179, debugging shows e == NULL) without even having run over the inserted loop. Ive set breakpoints etc, and still gives error6 without even having read the extra code. What's going on here? Im pretty new to C and parallel programming so its probably something fundamental. Would appreciate any help!
input format:
number_of_cores
number_of_pages
...
page_names
...
page_links
output format:
...
page_rank
...
code
#include <assert.h>
#include <math.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static const double D = 0.85;
static const double EPSILON = 0.005;
int ncores;
int npages;
struct webpage** pages;
int maxdepth;
struct webpage* has(char s[20], int e);
void* threadf(void* ptr);
int quit(void);
double rec(int s, int f, int depth);
struct webpage {
char name[20];
double oldrank;
double rank;
struct node* in;
int incount;
int outcount;
};
struct node {
struct webpage* data;
struct node* next;
};
struct arg {
int s;
int f;
int depth;
double ret;
};
struct webpage*
has(char s[20], int e) {
int p;
for (p=0; p<e; ++p) {
if (strcmp(s, pages[p]->name) == 0) {
return pages[p];
}
}
return NULL;
}
void *
threadf(void* ptr) {
struct arg* curr = (struct arg*)ptr;
curr->ret = rec(curr->s, curr->f, curr->depth);
}
int
quit(void) {
int i;
for(i=0; i<npages; ++i) {
struct node* curr = pages[i]->in;
struct node* next;
while(curr != NULL) {
next = curr->next;
free(curr);
curr = next;
}
free(pages[i]);
}
free(pages);
return 0;
}
double
seq(int s, int f) {
double sum;
sum = 0;
int w;
for (w=s; w<=f; w++) {
struct webpage* curr = pages[w];
double ser;
ser = 0;
struct node* currn = curr->in;
while (currn != NULL) {
struct webpage* n = currn->data;
ser = ser + ((n->oldrank)/(n->outcount));
currn = currn->next;
}
double temp = (((1-D)/npages) + (D*ser));
sum = sum + pow((temp - curr->oldrank), 2);
curr->oldrank = curr->rank;
curr->rank = temp;
}
return sum;
}
double
rec(int s, int f, int depth) {
if (depth == maxdepth ) {
return seq(s, f);
} else {
if (s < f){
int m;
m = (s+f)/2;
struct arg l;
struct arg r;
l.s = s;
l.f = m;
l.depth = depth+1;
r.s = m+1;
r.f = f;
r.depth = depth+1;
pthread_t left, right;
pthread_create(&left, NULL, threadf, (void*) &l);
pthread_create(&right, NULL, threadf, (void*) &r);
pthread_join(left, NULL);
pthread_join(right, NULL);
double res;
res = l.ret + r.ret;
return res;
}
return seq(s, f);
}
}
int
main(void) {
if (scanf("%d", &ncores) != 1) {
printf("error1\n");
return quit();
}
if (scanf(" %d", &npages) != 1) {
printf("error2\n");
return quit();
}
int i;
char n[20];
pages = (struct webpage**)malloc(npages*sizeof(struct webpage*));
for (i=0; i<npages; ++i) {
if (scanf(" %c", n) != 1 || has(n, i) != NULL) {
printf("error3\n");
return quit();
}
pages[i] = (struct webpage*)malloc(sizeof(struct webpage));
struct webpage* curr = pages[i];
strcpy(curr->name, n);
curr->oldrank = 1/npages;
curr->in = NULL;
curr->incount = 0;
curr->outcount = 0;
}
int nedges;
if (scanf(" %d", &nedges) != 1) {
printf("error4\n");
return quit();
}
for (i=0; i<nedges; ++i) {
char f[20], t[20];
if (scanf(" %s %s", f, t) != 2) {
printf("error5\n");
return quit();
}
char from[20], to[20];
strcpy(from, f);
strcpy(to, t);
struct webpage* s = has(from, npages);
struct webpage* e = has(to, npages);
if (s == NULL || e == NULL) {
printf("error6\n");
return quit();
}
s->outcount++;
e->incount++;
struct node* new;
new = (struct node*)malloc(sizeof(struct node));
new->data = s;
if (e->in == NULL) {
e->in = new;
} else {
new->next = e->in;
e->in = new;
}
}
maxdepth = (log(ncores))/(log(2)) + 0.5;
while (sqrt(rec(0, npages-1, 0)) > EPSILON){
int c;
for (c=0; c<npages; ++c) {
struct webpage* curr = pages[c];
curr->oldrank = curr->rank;
}
}
int z;
for (z=0; z<npages; ++z) {
struct webpage* curr = pages[z];
printf("%s %.4lf\n", curr->name, curr->rank);
}
return quit();
}
sample input:
8
4
a
b
c
d
4
a a
output:
error6

char n[20];
[ ... ]
if (scanf(" %c", n) != 1 || has(n, i) != NULL) {
The %c format specifier for scanf reads only one character. So n consists of the character you typed plus whatever garbage happened to be on the stack before you called scanf(). If you use %s, it will consist of the character you typed plus a NUL byte for terminating the string plus garbage you don't care about.
Also note that you can limit the amount of characters scanf() reads by using a width specifier, as in:
scanf("%19s", n)
(meaning: read 19 characters and add a NUL byte). Otherwise, your buffer could overflow, possibly leading to arbitrary code execution (or at least a crash when used by non-malicious users).

Related

sscanf fails to read string and double seperated by space

I'm scanning values from a file and storing them in an array. I have a custom struct called NODE which looks like this:
typedef struct node
{
char *name;
double value;
struct node *parent;
struct node *left_child;
struct node *right_child;
} NODE;
This function receives a string and two unsigned integer pointers and returns the data that was read in the form of a NODE array:
NODE *readNodes(char filename[], unsigned int *numNodes, unsigned int *capacity)
{
FILE *f = fopen(filename, "r");
if (f == NULL)
{
exit(1);
}
*numNodes = 0;
*capacity = 1;
int scanResult;
char *resultString = NULL;
char inputString[101];
NODE *nodes = (NODE *)malloc(sizeof(NODE) * (*capacity));
while (1)
{
while (*numNodes >= *capacity)
{
*capacity *= 2;
nodes = (NODE *)realloc(nodes, sizeof(NODE) * (*capacity));
}
resultString = fgets(inputString, 100, f);
if (resultString == NULL || (strcmp("\n", resultString) == 0))
{
break;
}
scanResult = sscanf(inputString, "%s %lf", nodes[*numNodes].name, &(nodes[*numNodes].value));
if (scanResult != 2)
{
*numNodes = 0;
*capacity = 0;
free(nodes);
return NULL;
}
nodes[*numNodes].parent = NULL;
nodes[*numNodes].left_child = NULL;
nodes[*numNodes].right_child = NULL;
*numNodes++;
}
return nodes;
}
The file it's reading from looks like this:
X 0.01
F 0.19
G 0.21
J 1.39
B 1.56
Y 1.96
H 2.08
Z 2.50
P 2.54
C 2.66
U 2.82
M 2.88
D 3.07
K 3.12
V 3.40
R 3.78
T 4.29
L 4.52
S 4.64
N 4.66
I 5.71
E 7.22
O 7.88
A 9.71
0 17.11
I can see from the debugger that it correctly reads a line but the sscanf fails somehow. I tried only scanning the string but that also fails. The return value of the sscanf is always 0 which would mean that it could not scan anything.
This is the full code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct node
{
char *name;
double value;
struct node *parent;
struct node *left_child;
struct node *right_child;
} NODE;
typedef struct queue
{
unsigned int front, end, size;
unsigned int capacity;
NODE *array;
} QUEUE;
NODE *readNodes(char filename[], unsigned int *numNodes, unsigned int *capacity)
{
FILE *f = fopen(filename, "r");
if (f == NULL)
{
exit(1);
}
*numNodes = 0;
*capacity = 1;
int scanResult;
char *resultString = NULL;
char inputString[101];
NODE *nodes = (NODE *)malloc(sizeof(NODE) * (*capacity));
while (1)
{
while (*numNodes >= *capacity)
{
*capacity *= 2;
nodes = (NODE *)realloc(nodes, sizeof(NODE) * (*capacity));
}
resultString = fgets(inputString, 100, f);
if (resultString == NULL || (strcmp("\n", resultString) == 0))
{
break;
}
scanResult = sscanf(inputString, "%s %lf", nodes[*numNodes].name, &(nodes[*numNodes].value));
if (scanResult != 2)
{
*numNodes = 0;
*capacity = 0;
free(nodes);
return NULL;
}
nodes[*numNodes].parent = NULL;
nodes[*numNodes].left_child = NULL;
nodes[*numNodes].right_child = NULL;
*numNodes++;
}
return nodes;
}
int main()
{
QUEUE freeNodes;
freeNodes.array = readNodes("./data/input.txt", &(freeNodes.size), &(freeNodes.capacity));
for (int i = 0; i < freeNodes.size; i++)
{
printf("%s\n", freeNodes.array[i].name);
}
free(freeNodes.array);
return 0;
}

How Can Read Values from File, store them in a structure and find their average, sum, product etc... using C

#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<windows.h>
#define SIZE 1024
typedef struct rational
{
int numerator;
int denominator;
struct rational *next;
}rational;
double add_rationals(rational*);
void multiply_rationals();
void subtract_rationals();
void divide_rationals();
void read_data(FILE*, int[], int*);
void display_values(rational*);
rational * createList(int []);
int main()
{
system("cls");
FILE* ifp;
ifp = fopen("file.txt", "r");
int data[SIZE] ={0};
int sz = SIZE;
read_data(ifp, data, &sz);
printf("\nRead Integer Count:%d\n", sz);
rational* HEAD = createList(data);
display_values(HEAD);
/*
want to start after the 1st number because 1st number is size of arr
data[0] is the 1st number we just read from the text
*/
//display_values(HEAD, data[0]); // passing data[0] as size cuz the 1st number is size
}
// double add_rationals(rational* r)
// {
// rational* c;
// c = r;
// static double x = 0 , y = 0, sum;
// x = r->numerator;
// y = r->denominator;
// while(c->next != NULL)
// {
// sum = x/y + add_rationals(r->next);
// }
// return sum;
// }
rational * createList(int data[])
{
rational *head = NULL;
rational *temp = NULL;
rational *p = NULL;
rational *r = NULL;
int count = 0;
for (int i = 1; i < 5; i++)
{
temp = (rational*)malloc(sizeof(double));
temp->numerator = data[i];
temp->denominator = data[++i];
temp->next = NULL;
if(head == NULL) // Checking if the List has started yet
{
count++;
head = temp;
printf("\nHEAD NUMERATOR: %d, HEAD DENOMINATOR: %d\n\n", head->numerator, head->denominator);
}
else
{
p = head;
while (p->next != NULL)
{
count++;
p = p->next;
}
p->next = temp;
}
}
}
void display_values(rational* HEAD)
{
rational* o = NULL;
o = HEAD;
while(o->next != NULL)
{
printf("\n\nNUM: %d, DEN: %d", o->numerator, o->denominator);
o = o->next;
}
}
void read_data(FILE* fptr, int d[], int*size)
{
*size = 0;
while ((fscanf(fptr, "%d", &d[*size])) == 1)
(*size)++;
}
PROBLEMS>>>
I am unable to display all the elements from the linked list in the function void display_values() function
The pre-requisites are like this .. take the 1st number from a text file and create an array of that size...
Let me show you with example:
2 5 2 6 7 being the integers in the text file
I want to read the 2nd and 4th items to a struct as numerators and the 3rd and 5th as denominators
I want 5/2 and 6/7 as rationals and do all these operations with them
Like Add, Sub, Mul , Div...etc
You are making it much too complex.
You should:
read a single integer from the input file
allocate an array of that number of rational struct
loop that number of times reading one struct and making it point to the next in the array
make next=NULL for the last element of the array
That way, you use one single malloc, and avoid the data integer array.
Possible code:
...
rational* read_data(FILE*, int*);
...
rational* HEAD = read_data(ifp, &sz);
printf("\nRead Integer Count:%d\n", sz);
display_values(HEAD);
...
rational* read_data(FILE* fptr, int* size)
{
*size = 0;
if (1 != fscanf(fptr, "%d", size)) return NULL;
rational* ls = malloc(*size * sizeof(rational)); // never cast return value of malloc!
for (int i = 0; i < *size; i++) {
if (2 != fscanf(fptr, "%d%d", &ls[i].numerator, &ls[i].denominator)) {
free(ls);
return NULL;
}
ls[i].next = ls + i + 1; // by definition same as &(ls[i+1])
}
ls[*size - 1].next = NULL;
return ls;
}
But you should add some error processing for fopen returning NULL or read_data returning NULL (file read error)...
there are multiple problems in your code, I corrected them below in comments:
rational* createList(int data[])
{
rational *head = NULL;
rational *temp = NULL;
rational *p = NULL;
rational *r = NULL; // this variable is not used
int count = 0; // I didn't see the purpose of this variable
for (int i = 1; i < 5; i++) // the 5 is a magic number,
{ //if the input file changes, the code will not run as intended
temp = (rational*)malloc(sizeof(double)); // space should be allocated for rational type not double type
temp->numerator = data[i];
temp->denominator = data[++i];
temp->next = NULL;
if(head == NULL)
{
count++;
head = temp;
printf("\nHEAD NUMERATOR: %d, HEAD DENOMINATOR: %d\n\n", head->numerator, head->denominator);
}
else
{
p = head;
while (p->next != NULL)
{
count++;
p = p->next;
}
p->next = temp;
}
}
// the return value for this function is missing.
}
void display_values(rational* HEAD)
{
rational* o = NULL;
o = HEAD;
while(o->next != NULL) // this condition will miss the last node of the linked list
{
printf("\n\nNUM: %d, DEN: %d", o->numerator, o->denominator);
o = o->next;
}
}

C passing pointer of a rbtree member of a struct for further processing

I want to read all pInd out of my rbtree neighbourList and store them in an array. The int pInd is simply the index for another array where I want to change values according to the stored adresses in my rbtree.
I have a array of structs (Pixel) and rbtree within each pixel holding the adress of neigbours.
//File rbtree.h
typedef struct rbtree_node_t {
int rInd;
int pInd;
struct rbtree_node_t* left;
struct rbtree_node_t* right;
struct rbtree_node_t* parent;
enum rbtree_node_color color;
} *rbtree_node;
typedef struct rbtree_t {
rbtree_node root;
} *rbtree;
//File rbtree.c
rbtree rbtree_create() {
rbtree t = malloc(sizeof(struct rbtree_t));
t->root = NULL;
verify_properties(t);
return t;
}
//----------------------------------------
//File main.c
typedef struct _Pixel
{
int mean;
rbtree neighbourList;
int index;
}Pixel;
void init(Pixel* p)
{
...
r[index].neighbourList = rbtree_create();
...
}
//----------------------------------------
void changepixel(Pixel* p,int index)
{
int *arr=NULL;
int i;
int size;
rbtree npl = r[index].neigbourList;
size = count(npl);
arr = calloc(size, sizeof(int));
AddNodeToArray(npl, arr, 0);
for (i=0; i<size; i++)
{
printf("arr[%d]: %d\n", i, arr[i]);
}
}
int AddNodeToArray(rbtree node, int arr[],int i);
{
if(node == NULL)
return i;
arr[i] = node->pInd;
i++;
if(node->left != NULL)
i = AddNodeToArray(node->left, arr, i);
if(node->right != NULL)
i = AddNodeToArray(node->right, arr, i);
return i;
}
int count(rbtree* node)
{
int c = 1;
if (node == NULL)
return 0;
else
{
c += count(node->left);
c += count(node->right);
return c;
}
}
//------------------------------
Pixel *p;
p = malloc((nx*ny)*sizeof(struct _Pixel));
Pixel p = r[10];
print_tree(p.npList);
changepixel(p,p.label);
Could someone explain me why printing the tree with
void print_tree_helper(rbtree_node n, int indent);
void print_tree(rbtree t) {
print_tree_helper(t->root, 0);
puts("");
}
void print_tree_helper(rbtree_node n, int indent) {
int i;
if (n == NULL) {
fputs("<empty tree>", stdout);
return;
}
if (n->right != NULL) {
print_tree_helper(n->right, indent + INDENT_STEP);
}
for(i=0; i<indent; i++)
fputs(" ", stdout);
if (n->color == BLACK)
printf("%d(%d)_bl\n", (int)n->rInd,(int)n->pInd);
else
printf("<%d>(%d)_re\n", (int)n->rInd,(int)n->pInd);
if (n->left != NULL) {
print_tree_helper(n->left, indent + INDENT_STEP);
}
}
works whereas my change doesen't? Or how to make it working using all the adresses found in a three for further working with these values?
GCC gives the error:
in function 'count' and in function 'AddNodeToArray'
request for member 'left' in something not a structure or union
Thank you in advance.
There are too many mistakes in your code. But for count and AddNodeToArray the main problem is that you confused with rbtree_node and rbtree types. rbtree_node is the struct with data you need, but rbtree is the struct with only one member - pointer to the root of the tree of type rbtree_node.
I could not test your code to point all of the errors, at least because it's not complete. However I guess to correct it you could try this.
count should be
int count_helper(rbtree_node node) {
int c = 1;
if (node == NULL)
return 0;
else {
c += count_helper(node->left);
c += count_helper(node->right);
return c;
}
}
int count(rbtree tree) {
if (tree == NULL)
return 0;
else {
return count_helper(tree->root);
}
}
and AddNodeToArray something like this
int AddNodeToArray_helper(rbtree_node tree, int arr[], int i) {
if(node == NULL)
return i;
arr[i] = node->pInd;
i++;
if(node->left != NULL)
i = AddNodeToArray_helper(node->left, arr, i);
if(node->right != NULL)
i = AddNodeToArray_helper(node->right, arr, i);
return i;
}
int AddNodeToArray_helper(rbtree tree, int arr[], int i) {
return AddNodeToArray_helper(tree->root, arr, i);
}

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.

Hashing, linked list, delete node

My task is to delete a node from a array of pointers which point to structure.
My code doesn't work and I just don't know why:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Jmena4.h"
#define LENGTH 101
#define P 127
#define Q 31
typedef struct node {
char *name;
struct uzel *next;
} NODE;
int hash(const char Name[]) {
int i;
int n = strlen(Name);
int result;
result = Name[0] * P + Name[1] * Q + Name[n - 1] + n;
return result % LENGTH;
}
void Insert(NODE *array[], const char *name) {
NODE *u;
int h;
u = (NODE*)malloc(sizeof(NODE));
u->name = name;
h = hash(name);
u->next = array[h];
array[h] = u;
}
int Search(NODE *array[], const char *name) {
NODE *u;
u = array[hash(name)];
while (u != NULL) {
if (strcmp(u->name, name) == 0) {
printf("%s\n", u->name);
return 1;
}
u = u->next;
}
printf("Name: %s wasn't found\n", name);
return 0;
}
int Delete(NODE *array[], const char *name) {
NODE *current;
NODE *previous;
int position = hash(name);
current = array[position];
previous = NULL;
while (current != NULL) {
if (strcmp(current->name, name) == 0) {
if (previous == NULL) {
array[position] = current->next;
return 1;
} else {
previous->next = current->next;
current = NULL;
return 1;
}
}
previous = current;
current = current->next;
}
return 0;
}
int main() {
int i;
NODE *array[LENGTH];
for (i = 0; i < LENGTH; i++) {
array[i] = NULL;
}
for (i = 0; i < Pocet; i++) {
Insert(array, Jmena[i]);
}
for (i = 0; i < PocetZ; i++) {
Delete(array, JmenaZ[i]);
}
Search(array, "Julie");
system("PAUSE");
return 0;
}
EDIT 1: I changed names of variables and instead of position = array[position] should be current = array[position], but it still doesn't work.
EDIT 2 : In array Jmena is string "Julie" and I can search it after Insert function, but after I delete strings from JmenaZ which not included "Julie" program output is: Name: Julie wasn't found.
For one thing, current isn't initialized before it gets tested in the while loop.

Resources