lundi 4 décembre 2017

Access violation exception while using std::string, other types are ok

so I'm writing my own vector class and it goes pretty well but I ran into problems with string type. Whole class is template and does pretty much same stuff as std::vector does, it works on int, double, float, char, but when it comes to std::string... it doesnt. Even the simpliest method crashes and throws read access violtion. Here is a bit of code

Part of header file

template <class T>
class MyVector{
    std::unique_ptr<T[]> m_array;
    int m_size; 
    int m_capacity; 
};

Constructor

template <class T>
MyVector<T>::MyVector() : m_capacity(2), m_size(0) {
    m_array = std::make_unique<T[]>(m_capacity);
}

ExtendArray method

template <class T>
void MyVector<T>::extendArray() {
    m_capacity *= 2;
    std::unique_ptr<T[]> temp_array = std::move(m_array);
    m_array = std::make_unique<T[]>(m_capacity);
    std::copy(temp_array.get(), temp_array.get() + m_capacity / 2, m_array.get());
}

PushBack method

template <class T>
void MyVector<T>::pushBack(const T& p_element) {
    if (m_size == m_capacity) extendArray();
    m_array[m_size] = p_element;
    m_size++;
}

InsertAt method, inserts element at given index and then moves rest of array

template <class T>
void MyVector<T>::insertAt(int index, const T& p_element) { 
        if (m_size >= m_capacity - 1) extendArray();            
        if (m_array[index] == T{}) {
            m_array[index] = p_element;
            m_size++;
        }
        else {
            std::copy(m_array.get() + index, m_array.get() + m_capacity, m_array.get() + index + 1);
            m_array[index] = p_element;
            m_size++;
        }
}   

Problem 1 PushBack method works fine, I keep adding elements of all types (including string), and its ok. Problem happens when then I try to use insertAt method

int main() {    
    MyVector<std::string> vec;
    vec.pushBack("Ok here");
    vec.pushBack("Extending array now");
    vec.pushBack("Still no errors");
    vec.insertAt(1, "Here comes the exception");
    std::cin.get();
}

I get

Exception thrown at 0x589750B9 (vcruntime140d.dll) in MySTL.exe: 0xC0000005: Access violation writing location 0xB9B431B6.

If I do same thing on char, int, float, double, everything works fine.

Problem 2 I started this project on Ubuntu, compiled it with G++ and I had no problems with templates, now Im working on Windows, using VS 2017 Community and I need to add

template class MyVector<std::string>;
template class MyVector<int>;
template class MyVector<float>;

etc in my .cpp in order to compile this, if type isnt defined like that, it just dont compile... any other, better solution?

Problem 3 On G++ I had no problems with adding other classes to my vector, now I cant do that. Even If i declare simple class in .cpp like that for example

class Test {
    int m_x;
public:
    Test() {}
    Test(int p_x) : m_x(p_x) {}
    int getX() { return m_x; };
};

template class MyVector <Test>;

it doesnt work, I get a lot of compiler errors like this

error C2676: binary '==': 'Test' does not define this operator or a conversion to a type acceptable to the predefined operator

pointing to

if (m_array[index] == T{}) 

on G++ both NULL or T{} worked, now neither of they works.

Aucun commentaire:

Enregistrer un commentaire