扩展动态数组时出现字符串错误

时间:2021-01-13 09:35:24

标签: c++ oop

我在尝试将额外元素附加到动态数组时遇到问题。我知道我可以使用向量,但出于学术目的,我必须使用数组。

#include <iostream>

using namespace std;

template <class T>
class MyList
{
protected:
    T* elems;
    int itsSize;
public:
    MyList(int itsSize):itsSize(itsSize)
    {
        elems = new T[itsSize];
    }

    ~MyList()
    {
        delete [] elems;
    }

    int getSize()
    {
        return itsSize;
    }

    virtual void addElem(){}
    virtual void getElem(){}
};

template <class T>
class MyStack : public MyList<T>
{
    int counter;
public:
    MyStack(int size):MyList<T>::MyList(size){counter=0;}

    void addElem()
    {
        T* tmp = new T[counter+1];

        for (int i = 0; i<counter+1; i++)
            tmp[i] = MyList<T>::elems[i];
        counter++;

        delete [] MyList<T>::elems;
        MyList<T>::elems = tmp;

        cin >> MyList<T>::elems[counter-1];
        if(cin.fail())
        {
            cin.clear();
            string line;
            getline(cin, line);
            throw "Wrong String Input--> will enter 0";
        }

    }

    void getElem()
    {
        for(int i=counter-1; i>=0; i--)
        {
            cout << "Element-->" << MyList<T>::elems[i] << endl;
        }
    }

};


int main()
{
        int storeChoice;
        cout << "Would you like to store integers, strings or rectangles (1,2, or 3)?" << endl;
        cin >> storeChoice;

        if(storeChoice==1)
        {
            MyStack<int> numList(1);

            cout << "Enter num:";
            numList.addElem();

            bool choiceAddLoop = true;
            while(choiceAddLoop == true)
            {
                try
                {
                    char choiceAdd;
                    cout << "Would you like to enter another elem?(y/n)" << endl;
                    cin >> choiceAdd;
                    if(choiceAdd=='y')
                    {
                        try
                        {
                         cout << "Enter num:";
                         numList.addElem();
                        }
                        catch(const char* wrongInput)
                        {
                         cout << wrongInput << endl;
                        }
                    }
                    else if(choiceAdd=='n')
                    {
                        choiceAddLoop=false;
                        break;
                    }
                    else
                        throw "Invalid Input.";

                }
                catch(const char* invalidChoice)
                {
                    cout << invalidChoice;
                }
            }

                 cout << endl << "All Elements" << endl;
                 numList.getElem();
        }
        else if(storeChoice==2)
        {
            MyStack<string> stringList(1);

            cout << "Enter string:";
            stringList.addElem();

            bool choiceAddLoop = true;
            while(choiceAddLoop == true)
            {
                try
                {
                    char choiceAdd;
                    cout << "Would you like to enter another elem?(y/n)" << endl;
                    cin >> choiceAdd;
                    if(choiceAdd=='y')
                    {
                         cout << "Enter string:";
                         stringList.addElem();
                    }
                    else if(choiceAdd=='n')
                    {
                        choiceAddLoop=false;
                        break;
                    }
                    else
                        throw "Invalid Input.";

                }
                catch(const char* invalidChoice)
                {
                    cout << invalidChoice;
                }
            }

              cout << endl << "All Elements" << endl;
              stringList.getElem();
        }
        }

当我选择第一个选项(整数)时,代码将起作用:

Would you like to store integers, strings or rectangles (1,2, or 3)?
1
Enter num:22
Would you like to enter another elem?(y/n)
y
Enter num:3
Would you like to enter another elem?(y/n)
n

All Elements
Element-->3
Element-->22

Process returned 0 (0x0)   execution time : 5.162 s
Press any key to continue.

第二个选择(字符串)出现问题:

Would you like to store integers, strings or rectangles (1,2, or 3)?
2
Enter string:hello
Would you like to enter another elem?(y/n)
y
Enter string:terminate called after throwing an instance of 'std::length_error'
  what():  basic_string::_M_create

Process returned 3 (0x3)   execution time : 6.761 s
Press any key to continue.

两者的代码相同,为什么它只适用于整数?

1 个答案:

答案 0 :(得分:1)

调用 MyStack<T>::addElem() 时发生错误。当您将元素从旧数组复制到新数组时,您的循环应该在 counter 而不是 counter+1 处停止。正确版本:

for (int i = 0; i<counter; i++)
    tmp[i] = MyList<T>::elems[i];

访问超出范围的 MyList<T>::elems[counter] 会导致未定义的行为。对于 int 的情况,您很幸运,当前存储在那里的数据可以正确解释为整数,而 std::string 则运气不佳。所以你想解释为 std::string 的随机数据导致了你得到的错误。

Live demo