Search code examples
c++vectorinitializationclion

Why is my C++ program running fine with the debugger but not without it?


I am trying to recreate the vector class with its basic functions, but my program keeps exiting halfway through the operations. When I run the debugger it fully executes just fine. Here is what my vector class looks like:

template<class T>
class Vector {
    T* _array;
    size_t _size;
    size_t _capacity;


public:
    Vector() : _size(0), _capacity(8), _array(new T[_capacity]) { }
    ~Vector() { delete[] _array; }

    void _grow() {
        T* tmp = _array;
        size_t old_cap = _capacity;
        _capacity *= 2;
        _array = new T[_capacity];
        for (size_t i = 0; i < old_cap; i++) {
            _array[i] = tmp[i];
        }
        delete[] tmp;
    }

    void push_back(T const& item) {
        if (_size == _capacity) { _grow(); }
        _array[_size++] = item;
    }

    void pop_back() {
        _size--;
    }

    void insert(T item, int position) {
        // implement insert here
        for (int i = position; i < _size-1; i++) {
            _array[i+1] = _array[i];
        }
        _size++;
        if (_size == _capacity) {
            _grow();
        }
        _array[position] = item;
    }

    void remove(int position) {
        // implement remove here
        for (int i = position; i < _size-1; i++) {
            _array[i] = _array[i+1];
        }
        _size--;
    }

    T& operator[](int index) {
        // implement operator[] here
        return _array[index];
    }

    size_t size() const {
        return _size;
    }

    void clear() {
        // implement clear here
        _size = 0;
    }
};

And here is the code actually initializes the class object and calls its member functions:

template<class T>
void noisy_push_back(Vector<T>& vector, T item) {
    vector.push_back(item);
    std::cout << "vector.push_back(" << item << ')' << std::endl;
}

template<class T>
void print_vector(Vector<T>& vector) {
    std::cout << "vector =";
    for (int i = 0; i < vector.size(); i++) {
        std::cout << ' ' << vector[i];
    }
}

void test1() {
    std::cout << "--- Test 1 output ---\n" << std::endl;

    Vector<std::string> vector;

    noisy_push_back<std::string>(vector, "wonder");
    noisy_push_back<std::string>(vector, "yak");
    print_vector(vector);

    std::cout << std::endl;
    noisy_push_back<std::string>(vector, "bookshelf");
    noisy_push_back<std::string>(vector, "euphoria");
    print_vector(vector);
}

When I run the program normally, it adds "wonder" and "yak" and then prints the vector just fine. When it tries to push_back("bookshelf") it exits with Process finished with exit code -1073741819 (0xC0000005)

Any ideas?

I tried printing out the vector size right before it exits and it was as expected: size() = 2
Also when I try to run the debugger everything looks normal and the program runs just fine. I am using CLion by the way.


Solution

  • Your compiler should warn you about this; if it does not, turn up your warnings!

     Vector() : _size(0), _capacity(8), _array(new T[_capacity])
    

    You are trying to initialize your _array last, however, since your variables are declared in the order of:

        T* _array;
        size_t _size;
        size_t _capacity;
    

    Then _array will be initialized first. _capacity will be indeterminate at the time of initialization, thus you have Undefined Behaviour.