Thread: Need help creating linked list of vectors

  1. #1
    Registered User
    Join Date
    Jul 2012
    Posts
    11

    Need help creating linked list of vectors

    Hi, I am trying to create a linked list of vector in my program. And, obviously, it is not working. The program is now suffering from segmentation fault. And, by the way, I know that I could write this program without using linked list; however, as a part of my assignment, I must make a use of linked list. Here is the code for the program:

    Code:
    #include <iostream>
    #include <fstream>
    #include <string>
    #include <vector>
    #include <sstream>
    using namespace std;
    //Define a class to represent each Seismic Activity measurement event...
    class RedwoodBaySeismicData
    {
        string LocationID; //This is the station that owns this piece of data…
        string Date; //The date that the values were collected…
        string Time; //The time of day that the values were collected…
        double SeismicSize; //Magnitude of Earthquake
    
      public:
        RedwoodBaySeismicData();
        RedwoodBaySeismicData(string, string, string, double);
        //The first group of member functions are used to change values...
        //Functions are defined in the form of inlines.
        void SetID(string ID)
        {
            LocationID = ID;
        }
        void SetDate(string Day)
        {
            Date = Day;
        }
        void SetTime(string Hour)
        {
            Time = Hour;
        }
        void SetSeismicSize(double Magnitude)
        {
            SeismicSize = Magnitude;
        }
    
        //The second group allows controlled access to individual value in the class...
        string GetID()
        {
            return LocationID;
        }
        string GetDate()
        {
            return Date;
        }
        string GetTime()
        {
            return Time;
        }
        double GetSeismicSize()
        {
            return SeismicSize;
        }
     
    };
     
    //The default constructor sets the private variable members to a harmless value...
    RedwoodBaySeismicData::RedwoodBaySeismicData()
    {
      LocationID;
      Date;
      Time;
      SeismicSize = 0.0;
    }
    //This initializing  constructor allows you to create a object with value already set...
    RedwoodBaySeismicData::RedwoodBaySeismicData(string ID, string Day, string Hour,
      double Magnitude)
    {
      LocationID = ID;
      Date = Day;
      Time = Hour;
      SeismicSize = Magnitude;
    }
    class RedwoodBayDataList
    {
        vector < RedwoodBaySeismicData * > RedwoodBayDataSpots; 
          //Create a collection of location information...
        string FileName;
        int K;
      public:
        // void GiveRedwoodSeismicData(RedwoodBaySeismicData *X) {RedwoodBayDataSpots.push_back(X);}
        RedwoodBayDataList()
        {
            FileName = "RedwoodBaySeismicEventList.data";
            K = RedwoodBayDataSpots.size();
        }
        RedwoodBayDataList(RedwoodBaySeismicData);
        void DisplaySeismicInfo();
        void DisplayInfoForEachStation(int);
        void DisplayAlphaInfo(int)
        {
            DisplayInfoForEachStation(K);
        }
        void DisplayBetaInfo(int)
        {
            DisplayInfoForEachStation(K);
        }
        void DisplayGammaInfo(int)
        {
            DisplayInfoForEachStation(K);
        }
        void DisplayDeltaInfo(int)
        {
            DisplayInfoForEachStation(K);
        }
        void DisplayEpsilonInfo(int)
        {
            DisplayInfoForEachStation(K);
        }
    };
     
    //Allow the user to post the values for each location...
    void RedwoodBayDataList::DisplaySeismicInfo()
    {
     
     
      string Line, ID, Date, Hour;
      double Magnitude;
      fstream InFile("RedwoodBaySeismicEventList.data.txt", ios::in);
    
      string Command2;
      {
        cout << "Choices...................................................." <<
          endl;
        cout << "-----------------------------------------------------------" <<
          endl;
        cout << 
          "Enter the name of the one of the four stations below for which you would like to have the data for seismic activity" << endl;
        cout << "Alpha" << endl;
        cout << "Beta" << endl;
        cout << "Gamma" << endl;
        cout << "Delta" << endl;
        cout << "Epsilon" << endl;
        cout << "-----------------------------------------------------------" <<
          endl;
        cout << "Command: ";
        getline(cin, Command2);
      }
      RedwoodBaySeismicData *Buffer = new RedwoodBaySeismicData(ID, Date, Hour,
        Magnitude);
    
      cout << "\n\t============================================================="
        << endl; 
        //This section is the report...it's really all about the formatting...
      cout << "\tWeekly Report" << endl;
      cout << "\t==============================================================="
        << endl;
      cout << "\tLocation\tDate\t\tHour\tMagnitude" << endl;
      cout << "\t==============================================================="
        << endl;
     
     
     
      while (getline(InFile, Line))
      {
        ID = strtok((char*)Line.c_str(), ":");
        Date = strtok(0, ":");
        Hour = strtok(0, ":");
        Magnitude = atof(strtok(0, ":"));
     
        Buffer->SetID(ID);
        Buffer->SetDate(Date);
        Buffer->SetTime(Hour);
        Buffer->SetSeismicSize(Magnitude);
        RedwoodBayDataSpots.push_back(Buffer);
     
     
        if (RedwoodBayDataSpots.size() == 114)
          break;
     
      }
      InFile.close();
    
      if (Command2 == "Alpha")
      {
        for (K = 0; K < 23; K++)
        {
          DisplayAlphaInfo(K);
        }
    
      }
    
      else if (Command2 == "Beta")
      {
        for (K = 23; K < 47; K++)
          DisplayBetaInfo(K);
      }
      else if (Command2 == "Gamma")
      {
        for (K = 47; K < 70; K++)
          DisplayGammaInfo(K);
      }
      else if (Command2 == "Delta")
      {
        for (K = 70; K < 93; K++)
          DisplayDeltaInfo(K);
      }
      else if (Command2 == "Epsilon")
      {
        for (K = 93; K < 115; K++)
          DisplayEpsilonInfo(K);
      }
     
     
     
      cout << 
        "\t===============================================================\n\n" <<
        endl;
    }
    
    void RedwoodBayDataList::DisplayInfoForEachStation(int K)
    {
      RedwoodBaySeismicData *Buffer;
      cout << "\t" << Buffer->GetID() << "\t\t" << Buffer->GetDate() << "\t" <<
        Buffer->GetTime() << "\t" << Buffer->GetSeismicSize() << endl;
     
    
    }
    
    //Declare the functions...
    void RunIT();
    void Menu();
    void ChooseTheStation();
    
    int main()
    {
      RunIT();
      system("pause");
    }
    //This function implements a simple command processor...
    void RunIT()
    {
      RedwoodBayDataList RedwoodBayDataSpots;
      string Command1;
      int K;
      while (Command1 != "Quit")
      {
        Menu();
        cout << "Command: ";
        getline(cin, Command1);
        if (Command1 == "Report")
          RedwoodBayDataSpots.DisplaySeismicInfo();
      }
    }
    //This function tells the user what he or she can do...
    void Menu()
    {
      cout << "Choices...................................................." << endl;
      cout << "-----------------------------------------------------------" << endl;
      cout << "\tReport...displays the  report." << endl;
      cout << "\tQuit.....exits the program." << endl;
      cout << "-----------------------------------------------------------" << endl;
    }
    I learned about linked list just few days ago and I am still having hard time grasping its idea. I would greatly appreciate any suggestion.
    Last edited by andrewmills; 07-01-2012 at 12:24 PM.

  2. #2
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    There is actually no code relating to a linked-list in that code at all.
    You need a tutorial to follow. There is one on this site I believe.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  3. #3
    Registered User
    Join Date
    Jul 2012
    Posts
    11
    Quote Originally Posted by iMalc View Post
    There is actually no code relating to a linked-list in that code at all.
    You need a tutorial to follow. There is one on this site I believe.
    Actually, linked list might have been a wrong word to use. It is more like a pointer to the vector.

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    Is this you as well?
    Need help to get rid of segmentation fault

    Because you've (both?) made the same mistake of trying to pass a C++ string c_str() into strtok(). This does NOT work.

    > vector < RedwoodBaySeismicData * > RedwoodBayDataSpots;
    Seriously, make this a
    vector < RedwoodBaySeismicData > RedwoodBayDataSpots;
    and stop trying to do your own memory management in a C++ program. There really is no need for it at this stage.
    It will be so much easier to get something working without looking over your shoulder for the next segfault.

    Optimisation (if it is ever needed) comes MUCH MUCH later on.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    This post... seems familiar in some way. Are you guys in the same class?
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  6. #6
    Registered User
    Join Date
    Jul 2012
    Posts
    11
    Quote Originally Posted by hk_mp5kpdw View Post
    This post... seems familiar in some way. Are you guys in the same class?
    Most likely, we are in the same class, eventhough I don't know the person who posted that question here. The problem he was working on was our first assignment in the class.

  7. #7
    Registered User
    Join Date
    Jul 2012
    Posts
    11
    Quote Originally Posted by Salem View Post
    That is not me. Most likely he/she is one of the students in my class. The problem he was working on was our first assignment in the class.

    > vector < RedwoodBaySeismicData * > RedwoodBayDataSpots;
    Seriously, make this a
    vector < RedwoodBaySeismicData > RedwoodBayDataSpots;
    and stop trying to do your own memory management in a C++ program. There really is no need for it at this stage.
    As much as I love to get rid of that pointer in the vector, unfortunately, I can't do it. As a part of our assignment I must create a vector of the pointers.

  8. #8
    Registered User
    Join Date
    Jul 2012
    Posts
    11
    Hi everyone. First, I would like to thank everyone for their suggestions. And, the good news is I think I am just one step away from creating a program that my teacher specifically asked for. Everything looks ok. Most importantly, the vector of pointers does not seem to have any issues and it reads the data from the file without any problem. Now, whenever you read the file, the last line always replaces the first line. But, after the first line, everything is ok; it reads everything correctly.
    So, I was hoping if anyone could tell me what I am doing wrong here.
    Anyway, this is the code for the program:
    Code:
    #include <iostream>
    #include <fstream>
    #include <string>
    #include <vector>
    #include <sstream>
    using namespace std;
    //Define a class to represent each Seismic Activity measurement event...
    class RedwoodBaySeismicData
    {
        string LocationID; //This is the station that owns this piece of data…
        string Date; //The date that the values were collected…
        string Time; //The time of day that the values were collected…
        double SeismicSize; //Magnitude of Earthquake
    
      public:
        RedwoodBaySeismicData();
        RedwoodBaySeismicData(string, string, string, double);
        //The first group of member functions are used to change values...
        //Functions are defined in the form of inlines.
        void SetID(string ID)
        {
            LocationID = ID;
        }
        void SetDate(string Day)
        {
            Date = Day;
        }
        void SetTime(string Hour)
        {
            Time = Hour;
        }
        void SetSeismicSize(double Magnitude)
        {
            SeismicSize = Magnitude;
        }
    
        //The second group allows controlled access to individual value in the class...
        string GetID()
        {
            return LocationID;
        }
        string GetDate()
        {
            return Date;
        }
        string GetTime()
        {
            return Time;
        }
        double GetSeismicSize()
        {
            return SeismicSize;
        }
     
    
    };
     
    //The default constructor sets the private variable members to a harmless value...
    RedwoodBaySeismicData::RedwoodBaySeismicData()
    {
      LocationID;
      Date;
      Time;
      SeismicSize = 0.0;
    }
    //This initializing  constructor allows you to create a object with value already set...
    RedwoodBaySeismicData::RedwoodBaySeismicData(string ID, string Day, string Hour,
      double Magnitude)
    {
      LocationID = ID;
      Date = Day;
      Time = Hour;
      SeismicSize = Magnitude;
    }
    class RedwoodBayDataList
    {
        vector < RedwoodBaySeismicData * > RedwoodBayDataSpots; 
          //Create a collection of location information...
        string FileName;
        int K;
      public:
    
        RedwoodBayDataList()
        {
            FileName = "RedwoodBaySeismicEventList.data";
            K = RedwoodBayDataSpots.size();
        }
        RedwoodBayDataList(RedwoodBaySeismicData);
        void ChooseSpecificStation(int &);
        void DisplaySeismicInfo();
        void DisplayInfoForEachStation(int);
        void DisplayAlphaInfo(int)
        {
            DisplayInfoForEachStation(K);
        }
        void DisplayBetaInfo(int)
        {
            DisplayInfoForEachStation(K);
        }
        void DisplayGammaInfo(int)
        {
            DisplayInfoForEachStation(K);
        }
        void DisplayDeltaInfo(int)
        {
            DisplayInfoForEachStation(K);
        }
        void DisplayEpsilonInfo(int)
        {
            DisplayInfoForEachStation(K);
        }
    };
     
    
    //Displays the report for each station.
    void RedwoodBayDataList::DisplaySeismicInfo()
    {
     
      string Line, ID, Date, Hour;
      double Magnitude;
      
      fstream InFile("RedwoodBaySeismicEventList.data.txt", ios::in);
      while (getline(InFile, Line))
      {
        ID = strtok((char*)Line.c_str(), ":");
        Date = strtok(0, ":");
        Hour = strtok(0, ":");
        Magnitude = atof(strtok(0, ":"));
     
    
        RedwoodBaySeismicData *Buffer = new RedwoodBaySeismicData(ID, Date, Hour,
          Magnitude);
        RedwoodBayDataSpots.push_back(Buffer);
        RedwoodBayDataSpots[K] = Buffer;
    
        RedwoodBayDataSpots[K]->SetID(ID);
        RedwoodBayDataSpots[K]->SetDate(Date);
        RedwoodBayDataSpots[K]->SetTime(Hour);
        RedwoodBayDataSpots[K]->SetSeismicSize(Magnitude);
    
        if (RedwoodBayDataSpots.size() == 115)
          break;
     
      }
      InFile.close();
    
      ChooseSpecificStation(K);
      cout << "\t===============================================================\n\n" << endl;
    }
    
    void RedwoodBayDataList::DisplayInfoForEachStation(int K)
    {
      cout << "\t" << RedwoodBayDataSpots[K]->GetID() << "\t\t" <<
        RedwoodBayDataSpots[K]->GetDate() << "\t" << RedwoodBayDataSpots[K]
        ->GetTime() << "\t" << RedwoodBayDataSpots[K]->GetSeismicSize() << endl;
    }
    void RedwoodBayDataList::ChooseSpecificStation(int &K) 
      // // It lets you choose the specific stationn for the report 
    {
      string Command2;
      cout << "Choices...................................................." << endl;
      cout << "-----------------------------------------------------------" << endl;
      cout << "Choose one of the station below to have its report:" << endl;
      cout << "-----------------------------------------------------------" << endl;
      cout << "Alpha" << endl;
      cout << "Beta" << endl;
      cout << "Gamma" << endl;
      cout << "Delta" << endl;
      cout << "Epsilon" << endl;
      cout << "-----------------------------------------------------------" << endl;
      cout << "Command: ";
      getline(cin, Command2);
    
      cout << "\n\t============================================================="
        << endl;
      cout << "\tWeekly Report" << endl;
      cout << "\t==============================================================="
        << endl;
      cout << "\tLocation\tDate\t\tHour\tMagnitude" << endl;
      cout << "\t==============================================================="
        << endl;
     
      if (Command2 == "Alpha")
      {
        for (K = 0; K < 23; K++)
        {
          DisplayAlphaInfo(K);
        }
    
      }
    
      else if (Command2 == "Beta")
      {
        for (K = 23; K < 46; K++)
          DisplayBetaInfo(K);
      }
      else if (Command2 == "Gamma")
      {
        for (K = 46; K < 69; K++)
          DisplayGammaInfo(K);
      }
      else if (Command2 == "Delta")
      {
        for (K = 69; K < 92; K++)
          DisplayDeltaInfo(K);
      }
      else if (Command2 == "Epsilon")
      {
        for (K = 92; K < 115; K++)
          DisplayEpsilonInfo(K);
      }
    }
     
    void RunIT();
    void Menu();
    void ChooseTheStation();
    
    int main()
    {
      RunIT();
      system("pause");
    }
    //This function implements a simple command processor...
    void RunIT()
    {
      RedwoodBayDataList RedwoodBayDataSpots;
      string Command1;
      int K;
      while (Command1 != "Quit")
      {
        Menu();
        cout << "Command: ";
        getline(cin, Command1);
        if (Command1 == "Report")
          RedwoodBayDataSpots.DisplaySeismicInfo();
      }
    }
    //This function tells the user what he or she can do...
    void Menu()
    {
      cout << "Choices...................................................." << endl;
      cout << "-----------------------------------------------------------" << endl;
      cout << "\tReport...displays the  report." << endl;
      cout << "\tQuit.....exits the program." << endl;
      cout << "-----------------------------------------------------------" << endl;
    }
    Also this the sample content of my text file:
    [Text]
    Alpha:01232012:0100:2.7
    Alpha:01292012:0100:2.2
    Alpha:02022012:0100:2.1
    Alpha:02032012:0100:3.5
    Alpha:03012012:0100:5.4
    Alpha:03042012:0100:5.8
    Alpha:03112012:0100:5.7
    Alpha:03212012:0100:3.1
    Alpha:04052012:0100:2.8
    Alpha:04152012:0100:2.6
    Alpha:04162012:0100:1.3
    Alpha:04182012:0100:3.3
    Alpha:04222012:0100:3.7
    Alpha:05012012:0100:3.3
    Alpha:05012012:0100:4.5
    Alpha:05022012:0100:6.1
    Alpha:05032012:0100:6.0
    Alpha:05112012:0100:5.9
    Alpha:05122012:0100:6.4
    Alpha:06032012:0100:6.1
    Alpha:06142012:0100:5.9
    Alpha:06182012:0100:5.8
    Alpha:06222012:0100:5.2
    Beta :01232012:0100:3.7
    Beta :01292012:0100:3.2
    [/Text]

    I am sorry for making such a long post.

  9. #9
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Line 125, as Salem says, you can't do that.
    Find another way and it might start working properly.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  10. #10
    Registered User
    Join Date
    Jul 2012
    Posts
    11
    Quote Originally Posted by iMalc View Post
    Line 125, as Salem says, you can't do that.
    Find another way and it might start working properly.
    I might be wrong but I dont think it has to do anything with the Line 125. The only problem is that when the program reads the data from the text file it replaces the first line of the data with the last line. Except for the first line, it reads everything else correctly.

  11. #11
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    Quote Originally Posted by andrewmills
    I might be wrong but I dont think it has to do anything with the Line 125.
    The code on line 125 is wrong, resulting in undefined behaviour. So, the problem might have nothing to do with that, but because of undefined behaviour, you don't really know. Fix it first, e.g., by using the std::string functions instead of strtok.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  12. #12
    Registered User
    Join Date
    Dec 2005
    Posts
    136
    The signature of strtok and c_str() is:
    Code:
    char *strtok(char *s1, const char *s2);
    const char* c_str ( ) const;
    C++ Standard does not suggest the casting as u did for first argument.
    Code:
    ID = strtok((char*)Line.c_str(), ":");
    Better use some other method suggested in this post.

    For your problem, You have already pushed the buffer using push_back in vector, now what are you trying to do again here, It is incorrect:
    Code:
        RedwoodBayDataSpots[K] = Buffer;
    
        RedwoodBayDataSpots[K]->SetID(ID);
        RedwoodBayDataSpots[K]->SetDate(Date);
        RedwoodBayDataSpots[K]->SetTime(Hour);
        RedwoodBayDataSpots[K]->SetSeismicSize(Magnitude);
    S_ccess is waiting for u. Go Ahead, put u there.

  13. #13
    Registered User
    Join Date
    Jul 2012
    Posts
    11
    Quote Originally Posted by laserlight View Post
    The code on line 125 is wrong, resulting in undefined behaviour. So, the problem might have nothing to do with that, but because of undefined behaviour, you don't really know. Fix it first, e.g., by using the std::string functions instead of strtok.
    Hi laserlight. Thanks for your response. As you have suggested, I would definitely read my data values by using getline if it was not for the double variable "Magnitude". I don't know how to read the double variable by using string functions.

  14. #14
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    Quote Originally Posted by andrewmills
    As you have suggested, I would definitely read my data values by using getline if it was not for the double variable "Magnitude". I don't know how to read the double variable by using string functions.
    There are a few ways. The one I had in mind basically involved finding the positions of the various ":" delimiters then taking substrings, but now that you mention getline, there is a simpler option where you #include <sstream> then use a stringstream with getline:
    Code:
    istringstream ss(Line);
    getline(ss, ID, ":");
    getline(ss, Date, ":");
    getline(ss, Hour, ":");
    string temp;
    getline(ss, temp, ":");
    Magnitude = atof(temp.c_str());
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  15. #15
    Registered User
    Join Date
    Jul 2012
    Posts
    11
    For your problem, You have already pushed the buffer using push_back in vector, now what are you trying to do again here, It is incorrect:
    Code:
        RedwoodBayDataSpots[K] = Buffer;
    
        RedwoodBayDataSpots[K]->SetID(ID);
        RedwoodBayDataSpots[K]->SetDate(Date);
        RedwoodBayDataSpots[K]->SetTime(Hour);
        RedwoodBayDataSpots[K]->SetSeismicSize(Magnitude);
    Thanks maven. You were right. That was why the program was replacing the first line with the last line whenever it read the data from the file. Thanks for your help again.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Creating Doubly Linked List Help!!
    By newbiecprogram in forum C Programming
    Replies: 3
    Last Post: 11-29-2010, 12:00 PM
  2. i have a problen in creating a linked list
    By transgalactic2 in forum C Programming
    Replies: 2
    Last Post: 07-02-2009, 10:34 AM
  3. Creating a Sorted Linked List, Help Please!
    By larry_2k4 in forum C Programming
    Replies: 4
    Last Post: 04-28-2009, 01:12 AM
  4. Is this creating a linked list?
    By JFonseka in forum C Programming
    Replies: 6
    Last Post: 10-24-2007, 01:33 AM
  5. Creating Linked list in .NET
    By axp in forum Windows Programming
    Replies: 1
    Last Post: 05-15-2004, 12:41 AM