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

C++ Program crashes on passing object by value

本文关键字:崩溃 对象 按值传递 程序 C++      更新时间:2023-10-16

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

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

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

变量初始化顺序不正确。 当您使用

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

您调整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];
    }
}

您需要为ans_vector内的每vector拨打resize,或使用push_backemplace_back等,这对您来说可能更安全。

AlPHABET_SIZE 未在以下位置定义:

表[i].调整大小(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;
}

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

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

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

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

  • 看来你可以_other_nfa声明常量引用:

    NFA NFA::Concat(const NFA& other_nfa)

  • 没有回报。在你的Concat方法结束时,应该有sth。喜欢:

    return ansNFA;

  • 似乎在 Concat 中,您不会像 table 那样更改成员变量(顺便说一句,这对于成员变量来说不是好名字)。如果 Concat 不更改类成员,则应将其声明为 const:

    NFA NFA:

    :Concat(const NFA&other_nfa) const