Chariot
Chariot

Reputation: 335

Why I have an exception in this delete?

I'm trying to compile this code but when the compiler arrives to "delete[] vector" in resize function (with resize(5), not with resize(10)) an exception appears and I don't know what is happening. Where is the problem and why this code doesn't work? and how can I improve the program to do it without errors?

#pragma once
#include <stdlib.h>
#include <iostream>
#include <new> 
using namespace std;

template<class T>
class Vector
{
public:
    Vector() {
        m_vector = nullptr;
        m_nElements = 0;
    }
    ~Vector() {
        delete[] m_vector;
    }
    void resize(int tamany);
    T& operator[](int indx);
    int getNelements() { return m_nElements; }
    Vector(const Vector &v);
    Vector<T>& operator=(const Vector<T>& v);
private:
    T* m_vector;
    int m_nElements;
};
template<class T>
void Vector<T>::resize(int size) {
    T* tmp;
    tmp = new T[size];

    for (int i = 0; i < m_nElements; i++) {
        tmp[i] = m_vector[i];
    }
    if (m_vector != nullptr || m_nElements == 0) {
        delete[] m_vector; //exception here!
    }

    m_vector = new T[size]; 
    for (int i = 0; i < size; i++) {
        m_vector[i] = tmp[i];
    }
    m_nElements = size;
}
template<class T>
T& Vector<T>::operator[](int indx) {
    if (indx > m_nElements) {
        cout << "Error, out of limits\n";
        T tmp;
        return tmp;
    }
    else {
        return m_vector[indx];
    }
}
template<class T>
Vector<T>::Vector(const Vector & v)
{
    m_nElements = v.m_nElements;
    if (v.m_vector != nullptr) {
        m_vector = new T[m_nElements];
        for (int i = 0; i < m_nElements; i++) {
            m_vector[i] = v.m_vector[i];
        }
    }
}
template<class T>
inline Vector<T>& Vector<T>::operator=(const Vector<T>& v)
{
    if (this != &v) {
        m_nElements = v.m_nElements;
        if (m_vector != nullptr) {
            delete[] m_vector;
        }
        if (v.m_vector != nullptr) {
            m_vector = new T[m_nElements];
            for (int i = 0; i < m_nElements; i++) {
                m_vector = v.m_vector;
            }
        }
        else {
            m_vector = nullptr;
        }
    }
    return *this;
}
int main() {

    Vector<int> v;
    v.resize(10);
    for (int i = 0; i < v.getNelements(); i++) {
        v[i] = i;
    }
    v.resize(5);

    for (int i = 0; i < v.getNelements(); i++) {
        cout << v[i] << endl;
    }
    system("pause");
    return 0;
}

Upvotes: 0

Views: 44

Answers (1)

catnip
catnip

Reputation: 25388

In void Vector<T>::resize(int size) you create an array of size elements:

T* tmp;  
tmp = new T[size];

And then copy m_nElements elements to it:

for (int i = 0; i < m_nElements; i++) {
    tmp[i] = m_vector[i];
}

So, if m_nElements is greater than size, you will write past the end of the array.

The solution is to copy m_nElements or size elements, whichever is the smaller.

Upvotes: 2

Related Questions