0

I am implementing a small search engine.The information is taken from a file and all searches containing the word are returned.problem is when I am running the search function in while loop,there is a segmentation fault error but when i run it without a while loop,it runs smoothly..I have rechecked the code quite a few times but can't find any problem.Any help would be appreciated.

 //searches individual words which are given to it.array has some data in it
int search_word(string word,string array)
{
    int counter=0;
    size_t found;
    int i=0;
    for (i=array.find(word,0);i!=string::npos;i=array.find(word,i))
    {
       counter+=1;
       i++;
    }
   return counter;
}



//this is sorting(descending) the linked list of results and storing it in an array
void Rank()
{
   struct results *go;
   go=head;
   int array[54];
   int l=0;
   while (go->next!=0)
   {
       array[l]=go->number;
       array1[l]=go->result;
       go=go->next;
       ++l;
   }
   array[l]=go->number;
   array1[l]=go->result;
   int temp;
   string temp1;
   for (int k=0;k<l;k++)
   {
       for (int j=(k+1);j<l+1;j++)
       {
          if (array[k]<array[j])
          {
             temp=array[k];
             array[k]=array[j];
             array[j]=temp;
             temp1=array1[k];
             array1[k]=array1[j];
             array1[j]=temp1;
          }
        }                  
    }
    cout<<"Following results were found"<<endl;
    for (int a=0;a<l;++a)
    {
       cout<<"Result no."<<a<<endl;
       cout<<array1[a]<<endl;
       cout<<endl;
    }
 }

 //main search function                
 void search(string array[])
 {
    //words like the,a,he,they,would are low rank words
   ifstream fin;
   fin.open("lowRank.txt");
   string lowrank;
   int j=0;
   while (!fin.eof())
   {
       string buffer;
       do
       {
           getline(fin,buffer);
           lowrank+=" ";
           lowrank+=buffer;
           ++j;
       }
       while (!buffer.empty());
   }
   fin.close();
   cout<<"Enter a word or phrase"<<endl;
   //converting the string containing words into seperate strings by tockenisation
   string setofwords[10];
   char phrase[50];
   cin.get(phrase,50);
   int count=0;
   char *pointer= NULL;
   pointer=strtok(phrase," ");
   while (pointer!=NULL)
   {
       char *pointer= NULL;  
       setofwords[count]=pointer;    
       pointer=strtok(NULL," ");
       count+=1; 
       delete [] pointer;
   }      

   for (int i=0;i<54;i++)
   {
       int counter=0;int counter1=0;
       //searching for all words one by one in the below loop       
       for (int k=0;k<count;k++)    
       {         
          //searching if word is low rank
           size_t found;
           found=lowrank.find(setofwords[k]);                 
           if (found!=string::npos)
           {
               counter=search_word(setofwords[k],array[i]);
               if (counter>0)
               {                    
                   counter1+=1;
               }
           }
           else
           {                                        
               counter=search_word(setofwords[k],array[i]);
               counter1+=counter;                   
           }        
        } 
     if (counter1>0)
     {
         add_result(array[i],counter1);
     }
   }
   Rank();
 }

int main()
{
  //reading the data file and copying it into an a linked list 
   ifstream fin;
   fin.open("data.txt");
    while (!fin.eof())
    {      
        string url;
        string data;
        getline(fin,url);
        string buffer;
       do
       {
            getline(fin,buffer);           
            if (!buffer.empty())
            {
               data=buffer;
            }
       }
       while (!buffer.empty());
       add_node(url,data);
   }
  //copying linked list to an array
  string array[54];
  node *conductor;
  conductor=root;
  for (int i=0;i<54;i++)
  {
      array[i]=conductor->url+conductor->data;
      conductor=conductor->next;
  }                   

  fin.close();

  while (1)
  {              


         cout<<"*******************************SEARCH                                  
         ENGINE********************************"<<endl;
        cout<<endl;
        cout<<endl;
        cout<<endl;
        cout<<"1.Press 1 to search a word."<<endl;
      cout<<"5.Press 5 to quit without saving search results"<<endl;

     int ans; 

      cin>>ans;     
      if (ans==1)
      {     
          search(array);
          search(array);
      }

      else if (ans==5)
      {
          quit_without_saving();
      }
      }

system("PAUSE");
return 0;
}
User14229754
  • 85
  • 1
  • 12

2 Answers2

3

The segmentation fault is likely due to the usage of delete [] on a pointer that was not returned by a call to new[]: there is not a single instance of the keyword new in the code posted, but there is one instance of delete.

R. Martinho Fernandes
  • 209,766
  • 68
  • 412
  • 492
  • @User14229754 now is the time when you run the code through a debugger and try to isolate the problem to a small piece of code. I doubt anyone will bother doing that in your stead. – R. Martinho Fernandes Nov 21 '12 at 14:53
3

Your error is in these lines of code:

char phrase[50];
cin.get(phrase,50);
int count=0;
char *pointer= NULL;
pointer=strtok(phrase," ");
while (pointer!=NULL)
{
   char *pointer= NULL;  
   setofwords[count]=pointer;    
   pointer=strtok(NULL," ");
   count+=1; 
   delete [] pointer;
}

strtok actually returns you a pointer to a character within what you passed in, in this case phrase.

phrase was created on the stack.

You therefore cannot call delete[] on it. Incidentally you also cannot call delete[] on the middle of an allocated block, it must be exactly the pointer that was returned from a new[] call.

Incidentally if you need to change your code such that phrase needs to know its size at run-time, do not use new[] but make phrase into std::vector<char> instead, and you can use &phrase[0] to get to its first element. Once again, no need to call delete[]

CashCow
  • 29,087
  • 4
  • 53
  • 86
  • but phrase has to store several words which then i have to access.shouldn't it be std::vector??sorry,i am new with vectors. – User14229754 Nov 21 '12 at 15:05
  • you should parse them into vector. Note there are various ways to do this in C++ rather than use strtok, e.g. istream_iterator or boost::tokenize, that are re-entrant. (strtok won't work in multiple threads as it holds state). – CashCow Nov 21 '12 at 16:02