Need help with copy constructor for very basic implementation of singly linked lists

Posted by Jesus on Stack Overflow See other posts from Stack Overflow or by Jesus
Published on 2011-03-16T00:07:46Z Indexed on 2011/03/16 0:10 UTC
Read the original article Hit count: 239

Filed under:
|
|
|

Last week, we created a program that manages sets of strings, using classes and vectors. I was able to complete this 100%. This week, we have to replace the vector we used to store strings in our class with simple singly linked lists.

The function basically allows users to declare sets of strings that are empty, and sets with only one element. In the main file, there is a vector whose elements are a struct that contain setName and strSet (class).

HERE IS MY PROBLEM: It deals with the copy constructor of the class. When I remove/comment out the copy constructor, I can declare as many empty or single sets as I want, and output their values without a problem. But I know I will obviously need the copy constructor for when I implement the rest of the program. When I leave the copy constructor in, I can declare one set, either single or empty, and output its value. But if I declare a 2nd set, and i try to output either of the first two sets, i get a Segmentation Fault. Moreover, if i try to declare more then 2 sets, I get a Segmentation Fault. Any help would be appreciated!!

Here is my code for a very basic implementation of everything:

Here is the setcalc.cpp: (main file)

#include <iostream>
#include <cctype>
#include <cstring>
#include <string>
#include "help.h"
#include "strset2.h"

using namespace std;

// Declares of structure to hold all the sets defined
struct setsOfStr {
    string nameOfSet;
    strSet stringSet;
};

// Checks if the set name inputted is unique
bool isSetNameUnique( vector<setsOfStr> strSetArr, string setName) {
    for(unsigned int i = 0; i < strSetArr.size(); i++) {
        if( strSetArr[i].nameOfSet == setName ) {
            return false;
        }
    }
    return true;
}

int main(int argc, char *argv[]) {
    char commandChoice;
    // Declares a vector with our declared structure as the type
    vector<setsOfStr> strSetVec;

    string setName;
    string singleEle;
    // Sets a loop that will constantly ask for a command until 'q' is typed
    while (1) {
        // declaring a set to be empty
        if(commandChoice == 'd') {
            cin >> setName;
            // Check that the set name inputted is unique
            if (isSetNameUnique(strSetVec, setName)  == true) {
                strSet emptyStrSet;
                setsOfStr set1;
                set1.nameOfSet = setName;
                set1.stringSet = emptyStrSet;
                strSetVec.push_back(set1);
            }
            else {
                cerr << "ERROR: Re-declaration of set '" << setName << "'\n";
            }
        }
        // declaring a set to be a singleton
        else if(commandChoice == 's') {
            cin >> setName;
            cin >> singleEle;
            // Check that the set name inputted is unique
            if (isSetNameUnique(strSetVec, setName) == true) {
                strSet singleStrSet(singleEle);
                setsOfStr set2;
                set2.nameOfSet = setName;
                set2.stringSet = singleStrSet;
                strSetVec.push_back(set2);
            }
            else {
                cerr << "ERROR: Re-declaration of set '" << setName << "'\n";
            }
        }
        // using the output function
        else if(commandChoice == 'o') {
            cin >> setName;
            if(isSetNameUnique(strSetVec, setName) == false) {
                // loop through until the set name is matched and call output on its strSet
                for(unsigned int k = 0; k < strSetVec.size(); k++) {
                    if( strSetVec[k].nameOfSet == setName ) {
                            (strSetVec[k].stringSet).output();
                    }
                }
            }
            else {
                cerr << "ERROR: No such set '" << setName << "'\n";
            }
        }
        // quitting
        else if(commandChoice == 'q') {
            break;
        }
        else {
            cerr << "ERROR: Ignoring bad command: '" << commandChoice << "'\n";
        }
    }
    return 0;
}

Here is the strSet2.h:

#ifndef _STRSET_
#define _STRSET_

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

struct node {
    std::string s1;
    node * next;
};

class strSet {

private:
    node * first;
public:
    strSet ();  // Create empty set
    strSet (std::string s); // Create singleton set
    strSet (const strSet &copy); // Copy constructor
    // will implement destructor later

    void output() const;
    strSet& operator =  (const strSet& rtSide);  // Assignment


};  // End of strSet class

#endif  // _STRSET_

And here is the strSet2.cpp (implementation of class)

#include <iostream>
#include <vector>
#include <string>
#include "strset2.h"

using namespace std;

strSet::strSet() {
    first = NULL;
}

strSet::strSet(string s) {
    node *temp;
    temp = new node;
    temp->s1 = s;
    temp->next = NULL;
    first = temp;
}

strSet::strSet(const strSet& copy) {
    cout << "copy-cst\n";
    node *n = copy.first;
    node *prev = NULL;
    while (n) {
        node *newNode = new node;
        newNode->s1 = n->s1;
        newNode->next = NULL;
        if (prev) {
            prev->next = newNode;
        }
        else {
            first = newNode;
        }
        prev = newNode;
        n = n->next;
    }
}

void strSet::output() const {
    if(first == NULL) {
        cout << "Empty set\n";
    }
    else {
        node *temp;
        temp = first;
        while(1) {
            cout << temp->s1 << endl;
            if(temp->next == NULL) break;
            temp = temp->next;
        }
    }
}


strSet& strSet::operator =  (const strSet& rtSide) {
    first = rtSide.first;
    return *this;
}

© Stack Overflow or respective owner

Related posts about c++

Related posts about class