简体   繁体   中英

C++ segmentation fault using dynamic arrays of strings

My string-dynamic-array.cpp file

#include <iostream>
#include <string>

class DynamicArray
{
public:
    DynamicArray()
    : mCapacity(1), mNumberOfElements(0)
    {
        mArray = new std::string[mCapacity];
    }

    DynamicArray(int size)
    : mCapacity(size), mNumberOfElements(0)
    {
        mArray = new std::string[mCapacity];
    }

    DynamicArray(const DynamicArray& array)
    : mCapacity(array.getCapacity()), mNumberOfElements(array.length())
    {
        mArray = new std::string[mCapacity];
        for (size_t i = 0; i < mCapacity; ++i)
        {
            mArray[i] = array.get(i);
        }
    }

    ~DynamicArray()
    {
        delete[] mArray;
    }

    void add(std::string element)
    {
        if (mNumberOfElements >= mCapacity)
        {
            expand();
        }

        mArray[mNumberOfElements++] = element;
    }

    std::string get(int index) const
    {
        if (index > mNumberOfElements)
        {
            std::string exception = std::to_string(index) + " index is out of bounds.";
            
            std::cout << exception;
            return std::string();
        }

        if (index < 0)
        {
            if (mNumberOfElements + index < 0)
            {
                std::string exception = std::to_string(index) + " index result in " + std::to_string(mNumberOfElements + index) + " which is out of bounds.\n";
                
                std::cout << exception;
                return std::string();
            }

            return mArray[mNumberOfElements + index];
        }

        return mArray[index];
    }

    int length() const
    {
        return mNumberOfElements;
    }

    int getCapacity() const
    {
        return mCapacity;
    }
private:
    int mCapacity;
    int mNumberOfElements;
    std::string* mArray;

    void initialize(int from)
    {
        for (size_t i = from; i < mCapacity; ++i)
        {
            mArray[i] = std::string();
        }
    }

    void expand()
    {
        mCapacity *= 2;
        std::string* temporaryArray = new std::string[mCapacity];

        for (size_t i = 0; i < mCapacity; ++i)
        {
            temporaryArray[i] = mArray[i];
        }

        delete[] mArray;

        mArray = temporaryArray;

        initialize(mNumberOfElements);
    }
};

int main()
{
    DynamicArray strings;
    strings.add("Hello");
    strings.add("World");

    for (size_t i = 0; i < strings.length(); ++i)
    {
        std::cout << strings.get(i) << std::endl;
    }
}

My output

$ clang++ tests/string-dynamic-array.cpp -o tests/string-dynamic-array && ./tests/string-dynamic-array
[1]    14950 segmentation fault (core dumped)  ./tests/string-dynamic-array

I get a segmentation fault.

The issue as far as I've found is in the code where I expand the array, in the expand() function. I think it's in the for loop because the index of for loop is out of bounds of the original array.

I've tried this with int , it seems to work fine. How can I do this with strings?

As commented by UnholySheep. I changed my expand function a bit so the loop only runs till the size of the old array.

Updated expand function:

    void expand()
    {
        mCapacity *= 2;
        std::string* temporaryArray = new std::string[mCapacity];

        for (size_t i = 0; i < mNumberOfElements; ++i)
        {
            temporaryArray[i] = mArray[i];
        }

        delete[] mArray;

        mArray = temporaryArray;

        initialize(mNumberOfElements);
    }

In “expand” method you have deleted mArray, then, you copied the temporaryArray to it, while as far as I know, mArray's handle is not valid anymore. You need to pass temporaryArray's handle to mArray so you could use it as a new expanded array.

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