你好我用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;
}
即时获取段内存错误或内存错误消息
我知道这种类型的错误与你不应该访问的内存有关,但是我无法找到错误的地方。如果你能帮我的话
答案 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
分配了适量的内存。