简体   繁体   English

Malloc返回null

[英]Malloc returns null

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: 你好,我已经用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;
    }

and im getting either segfault either out of memory2 error message 和即时消息要么出现segfault要么出memory2错误消息

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 如果可以的话请帮助我

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. 字符串所需的存储量比字符串的长度大1 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, eg 您在其他许多地方都遇到相同(或更糟的问题)的问题,例如

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

Should be strlen(title) + 1 again. 应该再次strlen(title) + 1

You need to go through your program and make sure that all of the calls to malloc are requesting the correct size. 您需要遍历程序,并确保对malloc所有调用都请求正确的大小。

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. 顺便说一句,您可以通过不进行强制转换并参考要为其分配空间的指针的大小来避免malloc错误。 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 . 这意味着您可以很快看到您正在为p分配正确的内存量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM