C ++程序在按值传递对象时崩溃

时间:2016-02-02 16:50:49

标签: c++ oop

将另一个对象传递给函数时发生错误 - > a.Concat(b);

我刚刚从Java恢复到C ++项目。当我在此代码中按值传递对象时,则会发生错误。几乎每次它显示不同的错误消息,有时是坏的alloc,有时显示输出的一半。我尝试通过引用传递,并且还创建了一个复制构造函数,但两次尝试都失败了。

#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;
}

5 个答案:

答案 0 :(得分:7)

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;
}

您的变量初始化无序。当你使用

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

ALPHABET_SIZE包含垃圾,因为您尚未设置值。只需在for循环之前移动ALPHABET_SIZE = 3;,你就可以了。

我还建议您使用所有变量的成员初始化列表。在这种情况下,您的构造函数看起来像

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";
}

答案 1 :(得分:3)

您调整vector<vector<string>的大小但无法调整任何包含的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];
    }
}

您需要为resize内的每个vector致电ans_vector,或使用push_backemplace_back等,这可能更安全对你而言。

答案 2 :(得分:1)

AlPHABET_SIZE未在:

中定义
  

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

默认情况下,它包含一些垃圾值。这可能是你的问题。

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;
}

答案 3 :(得分:1)

ALPHABET_SIZE正在NFA的ctor中使用,尽管它尚未初始化。它会导致奇怪的行为。

您正在创建三个对象a,b,ab。在构造对象程序崩溃期间。它与传递引用/值或使用copy ctor无关。

答案 4 :(得分:1)

从第一眼看,我会说问题出现在table的矢量访问中,这将超出范围。

从设计角度来看,有几个问题:

  • 看来你_other_nfa可以被声明为const引用:

    NFA NFA::Concat(const NFA& other_nfa)

  • 没有回报。在你的Concat方法结束时应该有......像:

    return ansNFA;

  • 似乎在Concat中你不会改变你的成员变量,如table(对于成员变量来说,这不是一个好名字)。如果Concat没有更改类成员,则应将其声明为const:

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