0

hello I have written a program in C and i keep getting segmentation faults or not enough memory messages when i use malloc in one function my code is the following:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define W 1031
#define B 256

/*didn't recognise NULL otherwise in eclipse*/

#ifndef NULL
#define NULL   ((void *) 0)
#endif



/// structs ///
FILE *textlist;

struct coor
{
       int line;
       int col;
       struct coor *next;
       };
typedef struct coor coor, *coor_ptr;
struct file
{
       struct file *next;
       coor *c;
       char* filetitle;

       };
typedef struct file file, *file_ptr;

struct tree
{
       char *word;
       struct tree *left, *right;
       file_ptr list ;
       };
typedef struct tree tree, *tree_ptr;


tree_ptr hasht[1031];

/// functions ///
int B_Mod_W (int x)
{
if (x == 0)
return 1;
return ((B % W) * (B_Mod_W(x - 1) % W)) % W;
/* (B^x) % W == ((B % W) * (B^(x-1) % W) ) % W */
}


int Hash_Value (char *s, int n, int i)
{
if (i > n - 1)
return 0;

/* (a*c + b) % W == ((a*c % W) + (b % W)) % W */
int hash = (B_Mod_W(n - i - 1) * (s[i] % W)) % W;

return (hash + Hash_Value(s, n, i + 1)) % W;
}

/*tree_ptr Insert_Tree (tree_ptr t, tree_ptr temp)
{
if (t == NULL)
return temp;

int comp = strcmp(temp->word, t->word);
if (comp < 0)
t->left = Insert_Tree(t->left, temp);
else if (comp > 0)
t->right = Insert_Tree(t->right, temp);
return t;
}*/

tree_ptr Make_Tree(char *w)
{
tree_ptr temp;
temp=(tree_ptr)malloc(sizeof(tree));
if(temp==NULL)
{
printf("out of memory2");
exit(4);
}
temp->left=NULL;
temp->right=NULL;
temp->list=NULL;
temp->word=(char *)malloc(strlen(w)*sizeof(char));
strcpy(temp->word, w);
//printf("%s",temp->word);
return temp;
}

coor_ptr Make_Coor(int c, int l)
{
//printf("%d,%d  ",l,c);//gia debug
coor_ptr p;
p=(coor*)malloc(sizeof(coor));
if (p==NULL)
{
printf("out of memory1");
exit(4);
}
p->col=c;
p->line=l;
p->next=NULL;
return p;

}

file_ptr Make_File(char* title)
{
file *temp;
temp=(file*)malloc(sizeof(file));
if(temp==NULL)
{
printf("out of memory2");
exit(4);
}
temp->filetitle=(char*)malloc(sizeof(title)*sizeof(char));
strcpy(temp->filetitle,title);
temp->next=NULL;
temp->c=NULL;
return temp;
}

coor_ptr Insert_Coor (coor_ptr p, coor_ptr head)
{
if (head==NULL)return p;
head->next=Insert_Coor(p, head->next);
return head;
}

/*inserts new file node in the end of existing file list*/
/*file_ptr Insert_File(file_ptr p ,file_ptr head)
{

if (head==NULL)

return p;
head->next = Insert_File(head->next, p);
return head;
}
*/

//returns 0 if not found 1 if found
/*int check(tree_ptr root, tree_ptr tempword)
{
if (root == NULL)
return 0;
tree_ptr p1=root;
int comp = strcmp(tempword->word, root->word);
while (p1)
{
if (comp==0)return 1;
else if (comp<0) p1=p1->left;
else p1=p1->right;
}
return 1;
}*/
/*puts every word in the right table creating tree
coordinates list etc*/

void putintable(char *word,int line,int col,char* title)
{
tree_ptr root,p1,next;
int n=strlen(word),h/*,temp*/,comp,comp2;
h=Hash_Value(word, n, 0);
//file_ptr tempfile;
coor_ptr pos;
root=hasht[h];
p1=root;
//printf("%d",h);

if(root==NULL)//if 1st word
{
root=Make_Tree(word);
root->list=Make_File(title);
root->list->c=Make_Coor(col,line);
hasht[h]=root;
return;
}
while(1)
{//printf("hey");
comp=strcmp(p1->word,word);
if (comp<0)
{
next=p1->left;
if (next==NULL)//p1 is last copy info here
{
p1->left=Make_Tree(word);
//tempfile=Make_File(title);
p1->left->list=Make_File(title);//Insert_File(tempfile, p1->left->list);
p1->left->list->c=Make_Coor(col,line);
//
return;
}

}
else if (comp<0)
{
next=p1->right;
if (next==NULL) //p1 is last copy info here
{
p1->right=Make_Tree(word);
//tempfile=Make_File(title);
p1->right->list=Make_File(title);//Insert_File(tempfile, p1->right->list);
p1->right->list->c=Make_Coor(col,line);
//
return;
}
}
else if (comp==0)//word already exists in tree
{
file_ptr t, prev;
t=p1->list;
prev=NULL;
comp2=strcmp(p1->list->filetitle, title);
while(t)
{
if (comp2==0)//there are other words already in the same file
{
//
pos=Make_Coor(col,line);
t->c=Insert_Coor(pos,t->c);
return;
}
   else //
    {
    prev=t;
    t=t->next;
    }
}
if (t==NULL)
{
/*if (prev==NULL)
{
p1->list=Make_File(title);
p1->list=Insert_File(tempfile, p1->right->list);
p1->list->c=Make_Coor(col,line);
return;
}*/
prev->next=Make_File(title);
//prev->next=Insert_File(tempfile, p1->right->list);
prev->c=Make_Coor(col,line);
return;
}
}
p1=next;
}



}

/*read words from each file and process them*/
void readfile(char *title)
{
 FILE *fp;
 int line=1,col=1,i=-1;
 char word[20], c;
 fp=fopen(title,"r");
 if(fp==NULL)
 {
    printf("error1");
exit(4);
 }
 while(1)
 {
i=-1;
    word[0]='\0';
    c=fgetc(fp);
    while (c!=EOF && c!=' ' && c!='\n')
    {
i++;
word[i]=c;
c=fgetc(fp);
}
//word[i+1]='\0';
if (word[0]!='\0')//not empty//
 {
    i++;
    word[i]='\0';
    //i=-1;
    //printf("%s",word);//gia debug
    char *temp1;
    temp1=(char*)malloc(sizeof(char)*strlen(word));
    strcpy(temp1,word);
putintable(temp1,line,col,title);
if(c==EOF)return;
else if(c=='\n')
{
line++;
col=1;
}
else if(c==' ')
{
//printf("ok");
col=col+1+strlen(word);
}
 }

else
{ //printf("k");
if(c==EOF)//file is finished
 return;
else if (c=='\n')//change line
{//printf("lol");
line++;
col=1;
}
else if (c==' ') col++;//move to next char same line
}
//  printf(" ");
//  printf("%d%d",line,col);
 }
 fclose(fp);
 return;
}


void readandedit()
{
int t;
char *title, title_ar[50];
    //read text titles//
textlist=fopen("textlist.txt","r");
if(textlist==NULL)
{
printf("could not open file");
exit(4);
}
while(1)
{

if (fgets(title_ar,50,textlist)==NULL)
{
break;
}
t=strlen(title_ar);
if(title_ar[t-1]=='\n')
{
title_ar[t-1]='\0';
}
title=(char*)malloc(t*sizeof(char));
if (title==NULL)
{
printf("no memory");
}
strcpy(title,title_ar);
//read each file and create wanted linked lists-trees//
readfile(title);
     }
     fclose(textlist);
 }

void seekanddestroy()
{
tree_ptr search;
int h, length;
char key[50];
scanf("%s",key);
length=strlen(key);
char *key1;
key1=(char*)malloc(sizeof(char)*length);
h=Hash_Value(key1,length,0);

/* search for keyword*/
search=hasht[h];
if (search==NULL)printf("wtf");
if(search==NULL || search->word==NULL)
{
printf("NOT FOUND");
return;
}
while (strcmp(search->word,key1)!=0)
{
if (strcmp(search->word,key1)>0)
search=search->left;
else
search=search->right;
if (search==NULL)
{
printf("NOT FOUND");
return;
}

}
//print desired results
printf("%s",key1);
file_ptr pos1=search->list;
while(pos1!=NULL)
{
coor_ptr pos2=search->list->c;
while(pos2!=NULL)
{
printf("%s(%d,%d)\n",pos1->filetitle, pos2->line, pos2->col);
pos2=pos2->next;
}
pos1=pos1->next;
}
return;
}
///main///
int main(void)
{
int i;
for(i=0;i<1031;i++)
hasht[i]=NULL;//initialize hash table
readandedit();

    seekanddestroy();
    return 0;
    }

and im getting either segfault either out of memory2 error message

i know that this type of errors have to do with accesing memory you are not supposed to but i can't find where I am mistaken. If you could please help me

vulpes
  • 13
  • 2
  • The commented-out functions are very helpful, indeed. – mafso Jul 31 '14 at 00:05
  • 2
    Hi - can you please edit your code and use proper indentation? Good indentation isn't just to make things look pretty - it makes your code easier to read, and it's easier to spot errors. Good programmers always use proper indentation. – Taryn East Jul 31 '14 at 00:05

1 Answers1

5

This causes buffer overflow:

temp->word=(char *)malloc(strlen(w)*sizeof(char));
strcpy(temp->word, w);

The amount of storage required for a string is 1 more than the length of the string. So:

temp->word = malloc( strlen(w) + 1 );
if ( !temp->word )
    // abort...

strcpy(temp->word, w);

Alternatively:

temp->word = strdup(w);
if ( !temp->word )
     // abort...

You have the same (or worse!) problem in a number of other places, e.g.

temp->filetitle=(char*)malloc(sizeof(title)*sizeof(char));

Should be strlen(title) + 1 again.

You need to go through your program and make sure that all of the calls to malloc are requesting the correct size.

BTW you can help to avoid malloc errors by not casting it and referring to the size of the pointer you are allocating space for. For example, replace

p=(coor*)malloc(sizeof(coor));

with

p = malloc( sizeof *p );

This means you can very quickly see that you are allocating the right amount of memory for p .

Community
  • 1
  • 1
M.M
  • 138,810
  • 21
  • 208
  • 365
  • i fixed this and im getting same errors, i cant find why my pointers are still null after malloc – vulpes Jul 31 '14 at 00:14
  • You proably missed some. Also your code is way too long. Make a SHORT program that gives the same problem and post it. – M.M Jul 31 '14 at 08:16