简体   繁体   中英

C++ Program crashes on passing object by value

Error occurs when I pass another object to a function -> a.Concat(b);

I have just reverted to C++ from Java for a project. When I pass object by value in this code, then an error occurs. Almost every time it is displaying a different error message, sometimes bad alloc, sometimes displaying half the output. I tried passing by reference and also made a copy constructor but both attempts failed.

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

using namespace std;

    class NFA
{
    public:
        NFA(string);
        NFA(vector<vector<string> >);
        NFA Concat(NFA other_nfa);
        NFA Union(NFA);
        NFA KleeneStar();
        void display();
        int GetNFASize(){ return ALPHABET_SIZE; }
        int getNoOfStates(){ return NO_OF_STATES; }

        vector<vector<string> > table;
        int ALPHABET_SIZE;
        int NO_OF_STATES;
    private:
};

NFA::NFA(string input)
{
    table.resize(2);
    NO_OF_STATES = 2;
    for(int i = 0; i < NO_OF_STATES; i++)
    {
        table[i].resize(ALPHABET_SIZE + 1);
    }
    table[0][0] = "2";
    table[0][1] = input;
    table[1][0] = "3";

    ALPHABET_SIZE = 3;
}

void NFA::display()
{
    for(int i = 0; i < table.size(); i++)
    {
        for(int j = 0; j < ALPHABET_SIZE; j++)
        {
            cout << table[i][j] << "\t";
        }
        cout << endl;
    }
}

NFA NFA::Concat(NFA other_nfa)
{
    vector<vector<string> > ans_vector;
    ans_vector.resize(ALPHABET_SIZE + other_nfa.ALPHABET_SIZE);

    for(int i = 0; i < NO_OF_STATES; i++)
    {
        for(int j = 0; j < ALPHABET_SIZE; j++)
        {
            ans_vector[i][j] = table[i][j];
        }
    }
    for(int i = other_nfa.NO_OF_STATES - 1; i < other_nfa.NO_OF_STATES; i++)
    {
        for(int j = 0; j < other_nfa.ALPHABET_SIZE; j++)
        {
            ans_vector[i][j] = other_nfa.table[i][j];
        }
    }
    ans_vector[NO_OF_STATES - 1][3] = other_nfa.table[0][0];
    NFA ansNFA(ans_vector);
}

NFA::NFA(vector<vector<string> >)
{

}

int main()
{
        NFA a("a");
        a.display();

        NFA b("b");
        b.display();

        NFA ab = a.Concat(b);

        system("pause");
        return 0;
}

In

NFA::NFA(string input)
{
    table.resize(2);
    NO_OF_STATES = 2;
    for(int i = 0; i < NO_OF_STATES; i++)
    {
        table[i].resize(ALPHABET_SIZE + 1);
    }
    table[0][0] = "2";
    table[0][1] = input;
    table[1][0] = "3";

    ALPHABET_SIZE = 3;
}

You variable initializations are out of order. When you use

table[i].resize(ALPHABET_SIZE + 1);

ALPHABET_SIZE contains garbage as you have not set a value yet. Just move ALPHABET_SIZE = 3; before the for loop and you should be okay.

I would also suggest you use a member initialization list for all variables to you can. In this case your constructor would look like

NFA::NFA(string input) : NO_OF_STATES(2), ALPHABET_SIZE(3)
{
    table.resize(2);
    for(int i = 0; i < NO_OF_STATES; i++)
    {
        table[i].resize(ALPHABET_SIZE + 1);
    }
    table[0][0] = "2";
    table[0][1] = input;
    table[1][0] = "3";
}

You resize a vector<vector<string> but fail to resize any of the contained vector s:

ans_vector.resize(ALPHABET_SIZE + other_nfa.ALPHABET_SIZE);

And then later you index into the nested vectors, which goes out of bounds:

for(int i = 0; i < NO_OF_STATES; i++)
{
    for(int j = 0; j < ALPHABET_SIZE; j++)
    {
        ans_vector[i][j] = table[i][j];
    }
}

You'll need to call resize for every vector inside ans_vector , or use push_back , emplace_back etc, which would probably be safer for you.

AlPHABET_SIZE is not defined in:

table[i].resize(ALPHABET_SIZE + 1);

by default, it contains some garbage value. This might be your problem.

NFA::NFA(string input)
{
    table.resize(2);
    NO_OF_STATES = 2;
    for(int i = 0; i < NO_OF_STATES; i++)
    {
        table[i].resize(ALPHABET_SIZE + 1);
    }
    table[0][0] = "2";
    table[0][1] = input;
    table[1][0] = "3";

    ALPHABET_SIZE = 3;
}

ALPHABET_SIZE is being used in the ctor of NFA though it was not initialized. it causes weird behaviour.

You are creating three objects a,b,ab. during construction of the object program crashes. it has nothing to do with pass by reference/value or using copy ctor.

From the first look I would say the problem lays in the vector-access of table , which would go out-of-range.

From design-point, several issues:

  • It seems you _other_nfa can be declared const reference:

    NFA NFA::Concat(const NFA& other_nfa)

  • There is no return. At the end of your Concat method there should be sth. like:

    return ansNFA;

  • It seems within Concat you don't change your member variables like table (which btw. is no good name for a member-variable). If Concat dosn't change the class members, you should declare it const:

    NFA NFA::Concat(const NFA& other_nfa) const

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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