Malloc返回null

时间:2014-07-31 00:03:09

标签: c pointers segmentation-fault malloc

你好我用C编写了一个程序,当我在一个函数中使用malloc时,我不断得到分段错误或没有足够的内存消息 我的代码如下:

#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;
    }

即时获取段内存错误或内存错误消息

我知道这种类型的错误与你不应该访问的内存有关,但是我无法找到错误的地方。如果你能帮我的话

1 个答案:

答案 0 :(得分:5)

这会导致缓冲区溢出:

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

字符串所需的存储量比字符串的长度多1。所以:

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

strcpy(temp->word, w);

可替换地:

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

您在许多其他地方遇到相同(或更糟!)的问题,例如

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

应该再次strlen(title) + 1

您需要完成所有程序并确保所有对malloc的调用都要求正确的大小。

BTW你可以通过not casting it帮助避免malloc错误并引用你为其分配空间的指针的大小。例如,替换

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

p = malloc( sizeof *p );

这意味着您可以非常快速地看到您为p分配了适量的内存。