

まず目標ですが、最後に0を返すことです。以下のプログラムは作ったメソッドが正しく動くかをテストするプログラムです。このプログラムを実行すると最後に0が返ってきません。これはおそらくappend()
または、resize()に問題があると思います。appendメソッドは最後の要素の直後に渡した値を入れるのが目的です。もし、要素を足すことによって合計の要素数が配列の大きさ以上になる場合は、resizeメソッドに今の配列の大きさの倍の値を渡して、その大きさの配列を新たに作り、その新しい配列に渡した値を最後の要素の直後に入れます。resizeメソッドは、渡された値の大きさの配列を作るのが目的です。コンパイルしてもエラーメッセージはでてきません。ただ、0が返ってきません。おそらく何かをずっと処理しているのだと思われます。わかる方いましたらよろしくお願いします。

**ArrayInt.h**

[code]

    #ifndef LAB1B_ARRAYINT_H
    #define LAB1B_ARRAYINT_H
    
    
    #include <iostream>
    #include <sstream>
    using std::cout;
    using std::endl;
    using std::string;
    
    
    
    class ArrayInt {
    private:
    
        int *array;
        int arraySize;
        int elements;
    
    public:
        ArrayInt();
        ArrayInt(int size);
        ~ArrayInt();
        int getSize();
        void resize(int size);
        void append(int value);
        string listElements();
    };
    
    
    #endif //PRA_WEEK1_ARRAYINT_H
    
[/code]

**ArrayInt.cpp**

[code]

    #include "ArrayInt.h"
    
    
    ArrayInt::ArrayInt()
    {
        //create an array that the size of 10
        arraySize = 10;
        array = new int[arraySize];
    }
    ArrayInt::ArrayInt(int size)
    {
        //create an array that the size of size
        //if size < 1
        //size = 10;
        arraySize = size;
    
        if(size < 1)
        {
            arraySize = 10;
        }
    
        array = new int[arraySize];
    }
    
    ArrayInt::~ArrayInt()
    {
        delete [] array;
    }
    
    int ArrayInt::getSize()
    {
        //return the the current size of the array
    
        return arraySize;
    }
    void ArrayInt::resize(int size)
    {
        //if size < getSize (if the new size is smaller than current size)
        //do nothing (don't change anything)
    
    
        if(size <= arraySize)
        {
            return;
        }
    
        //resize the array to the new size that is passed in
    
        //create new array to store previous values in it
        int *newArray = new int[size];
    
        //move the previous values to new array
        for(int i = 0; i < elements; i++)
        {
            newArray[i] = array[i];
        }
    
        //update the array size
        arraySize = size;
    
        //we don't need the old array anymore
        delete[] array;
    
        //array points to newArray so that the array gets new spaces
        array = newArray;
    }
    void ArrayInt::append(int value)
    {
        static int counter = 0;
        elements = counter;
    
        //if the next location >= current size
        if(elements >= arraySize)
        {
    
            //create a new array of size*2
            arraySize = arraySize * 2;
            resize(arraySize);
        }
        //adding the value that is passed in into the next available space in the array
        array[elements] = value;
    
        //increasing the counter and elements after append value
        counter++;
        elements++;
    
        cout << "append method: " << value << " is added to the array" << endl;
    }
    
    
    string ArrayInt::listElements()
    {
        string numList;
        std::stringstream ss;
        //return string that contains all numbers in the array numbers should be separated by comma
    
    
        //if the array is empty
        // returns the string "Empty Array"
        if(elements < 1)
        {
            return "Empty Array";
        }
    
        for(int i = 0; i < elements; i++)
        {
            ss << array[i] << ",";
        }
    
        ss >> numList;
    
        return numList;
    }
    
[/code]

**main.cpp**

[code]

    #include <iostream>
    #include "ArrayInt.h"
    
    using std::cout;
    using std::cin;
    using std::endl;
    using std::string;
    
    
    
    
    int main()
    {
    
        const int START = 7;
        const int UPDATE = 12;
        std::cout << "Testing setSize and auto expansion on appends" << std::endl;
        std::cout << "Also tests listElements" << std::endl << std::endl;
    
        ArrayInt room(START);
        std::cout << "Starting size should be " << START << " and is " << room.getSize() << std::endl;
        room.resize(UPDATE);
        std::cout << "After resize, size should be " << UPDATE << " and is " << room.getSize() << std::endl;
    
        std::cout << std::endl << "Now going to fill array and see if expands" << std::endl;
        for(int i = 0; i < UPDATE; i++)
        {
            room.append(2 * i + 1);
        }
    
        std::cout << "Filled with 12 values, no problem" << std::endl;
        std::cout << "Size should still be " << UPDATE << " and is " << room.getSize() << std::endl;
        std::cout << std::endl << "Adding one more" << std::endl;
    
        room.append(25);
    
        std::cout << "Size should now be " << 2 * UPDATE << " and is " << room.getSize() << std::endl;
    
        std::cout << std::endl << "Should show: 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25 " << std::endl;
        std::cout << "Array returns: " << room.listElements() << " ";
    
        std::cout << std::endl << std::endl;
    
    
        return 0;
    }
    
[/code]


CC BY-SA 4.0
2021-10-01T09:36:09.803
82797
2021-10-01T11:40:00.400
2021-10-01T10:21:30.427
45177
45177
question
c++
今回の問題はプログラムが正しく終わらないということです。最後に０を返すはずが０が返ってこず、ずっと何かの処理をしているようです。


デバッガで追えばわかりますが、原因は以下の箇所にあります。

[code]

        //if the next location >= current size
        if (elements >= arraySize)
        {
    
            //create a new array of size*2
            arraySize = arraySize * 2;
            resize(arraySize);
        }
    
[/code]

`arraySize = arraySize * 2;`により、`arraySize`は`12`から`24`になります。  
そして、`resize(24);`が呼ばれますが、`resize`の先頭の条件文は以下のようになっています。

[code]

        if(size <= arraySize)
        {
            return;
        }
    
[/code]

引数で渡された`size`が`24`、`arraySize`が`24`なので、上記条件を満たし、`array`に割り当てられたメモリを増やすことなく`return`してしまいます。  
あとは、割り当てられていないメモリに書き込んでバッファオーバーフローというわけです。


CC BY-SA 4.0
2021-10-01T11:40:00.400
82802
2021-10-01T11:40:00.400
43506
82797
answer