Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

Seg fault when i try to add a third word to a vector of words

Posted on 2004-11-09
2
Medium Priority
?
324 Views
Last Modified: 2010-04-17
Hi Experts:

So, i'm trying to write a function which receives a string and parses out the words, which are seperated by delimiters.   It's basically a strtok() function.   However, this confounded thing keeps crashing on the third word that I try to add to the word vector.   I left all my bug-hunting statements in the code, just so that anyone who needs them doesn't have to re-type them.   I took most of my comments out as i would suspect them to be highly useless to anyone else; they are a rather incoherent jumble of what I was thinking before and during the actual coding, and bear little relevance to the code itself.   Any help that can be offered on this code would be mighty appreciated.  

Thanks much in advance for any and all comments.

Pierre

==================================
#include <vector>
#include <iostream>
#include <string>

using namespace std;

void tokenize(vector<char*> words, int& numWords, char *line, char *delimiters)
{
      char *startCurWord, *endCurWord;
      char* curDelim;
      int lineLength;
      int delimLength;
   
      curDelim = delimiters;
      startCurWord = line;
   
      //get line length
      lineLength = strlen(line);
   
      //set startCurWord to line
      startCurWord = line;
   
      //loop:
      while((startCurWord - line) < lineLength)
      {
            endCurWord = strpbrk(startCurWord, delimiters);
            if(endCurWord)
            {
                  *endCurWord = '\0';
                  if(endCurWord - startCurWord > 0)
                  {
                        cout << "numWords: " << numWords << endl;
                        cout << "words.size(): " << words.size() << endl;
                        cout << "strlen(startCurWord): " << strlen(startCurWord) << endl;
                        words.push_back(new char[strlen(startCurWord)]);
//                        words.push_back((char*)malloc(strlen(startCurWord) * sizeof(char)));
                        numWords++;
                        words[numWords][0] = '\0';
                        cout << "numWords: " << numWords << endl;
                        cout << "words.size(): " << words.size() << endl;
                        cout << "startCurWord: " << startCurWord << endl;
                        cout << "before: \"" << words[numWords] << "\"" << endl;
                        strcpy(words[numWords], startCurWord);
                        cout << "after: \"" << words[numWords] << "\"" << endl;
                        cout << "numWords: " << numWords << endl;
                        cout << "words.size(): " << words.size() << endl;
                        cout << "===================================" << endl << endl;
                  }
            }
            else
            {
                  cout << "numWords: " << numWords << endl;
                  cout << "words.size(): " << words.size() << endl;
                  cout << "strlen(startCurWord): " << strlen(startCurWord) << endl;
                  words.push_back(new char[strlen(startCurWord)]);
//                  words.push_back((char*)malloc(strlen(startCurWord) * sizeof(char)));
                  numWords++;
                  words[numWords][0] = '\0';
                  cout << "numWords: " << numWords << endl;
                  cout << "words.size(): " << words.size() << endl;
                  cout << "startCurWord: " << startCurWord << endl;
                  cout << "before: \"" << words[numWords] << "\"" << endl;
                  strcpy(words[numWords], startCurWord);
                  cout << "after: \"" << words[numWords] << "\"" << endl;
                  cout << "numWords: " << numWords << endl;
                  cout << "words.size(): " << words.size() << endl;
                  cout << "===================================" << endl << endl;
            }    

            //  set startCurWord to end of current word + 1
            if(endCurWord)
                  startCurWord = endCurWord + 1;
            else
                  startCurWord = line + lineLength;

            //  if startCurWord - line < lineLegth, loop

      }

      return;
}

int main()
{
      int numWords, size;
      int i = 0;
      vector<char*> words;

      numWords = 0;
      char line[] = "aaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb ccc ddd";
//      char line[] = "aaa bbb ccc ddd";
//      char line[] = "This ain't a test line.   Pay no attention.";
//      char *line = "This is a test line.   Pay no attention.";
         
      tokenize(words, numWords, line, " ,.");
   
//      cout << numWords << endl;
   
//      for(words.begin(); i < numWords; i++)
//      cerr << words[i] << endl;
   
      system("PAUSE");
   
      return 0;
};    
0
Comment
Question by:Diceman_01
2 Comments
 
LVL 55

Accepted Solution

by:
Jaime Olivares earned 500 total points
ID: 12536452
I suspect on this line:
 words.push_back(new char[strlen(startCurWord)]);

I think must be:
 words.push_back(new char[strlen(startCurWord)+1]);   // reserve an extra space for ending null character

Vector of pointers could be some confusing because you have to pay attention to allocation and deallocation, if you are working with STL vectors, I suggest you to work with std::string objects, don't have to deal with allocation. Something like:

vector<string> words

Good luck,
Jaime.
0
 

Author Comment

by:Diceman_01
ID: 12536633
Hey Jaime;

thanks very much for your help.   After I asked the question, I kept searching the EE DB and came up wioth this code:

void tokenize(vector<string> &words, int& numWords, char *line, char *delimiters)
{
    char * pToken = strtok(line, delimiters);
    while( pToken )
    {
          words.push_back(pToken);
         pToken = strtok(0, delimiters);
    };     // while  

    numWords = words.size();
}

Well, it does exactly what I need it to do.   I have no idea why I couldn't see the solution earlier.   I suppose this is the reason why one needs to take a break when coding.   At any rate, just out of curiousity, I tried adding the extra space for the null, but to no avail.   However, you're right about the second idea of vector<string>.   Points to you dude.   Thanks again.

Pierre      
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This is about my first experience with programming Arduino.
If you are a mobile app developer and especially develop hybrid mobile apps then these 4 mistakes you must avoid for hybrid app development to be the more genuine app developer.
An introduction to basic programming syntax in Java by creating a simple program. Viewers can follow the tutorial as they create their first class in Java. Definitions and explanations about each element are given to help prepare viewers for future …
In this fourth video of the Xpdf series, we discuss and demonstrate the PDFinfo utility, which retrieves the contents of a PDF's Info Dictionary, as well as some other information, including the page count. We show how to isolate the page count in a…

810 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question