你好,我用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]=' ';
c=fgetc(fp);
while (c!=EOF && c!=' ' && c!='n')
{
i++;
word[i]=c;
c=fgetc(fp);
}
//word[i+1]=' ';
if (word[0]!=' ')//not empty//
{
i++;
word[i]=' ';
//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]=' ';
}
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;
}
和我得到要么段错误要么内存不足2错误消息
我知道这种类型的错误与访问内存有关,你不应该这样做,但我找不到我错在哪里。如果你能帮助我
这会导致缓冲区溢出:
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
的调用都请求正确的大小。
顺便说一句,您可以通过不强制转换它并引用您正在分配空间的指针的大小来帮助避免malloc错误。例如,替换
p=(coor*)malloc(sizeof(coor));
p = malloc( sizeof *p );
这意味着您可以很快看到您正在为p
分配正确数量的内存量。