如何清除检测到的堆损坏.类向量

How do i get rid of heap corruption detected. Class Vector

本文关键字:损坏 向量 检测 何清除 清除      更新时间:2024-09-21

我正在尝试制作自己的Vector,在我更改移动构造函数后,我检测到堆损坏:在正常块(#34115(之后。

这是移动构造函数:

template<typename T>
inline Vector<T>::Vector(Vector&& other)
: m_nrOfElements(std::exchange(other.m_nrOfElements, 0)), 
m_capacity(std::exchange(other.m_capacity, 0)), 
m_elements(std::exchange(other.m_elements, nullptr))
{

}

这是其总数中的代码:

#pragma once
#include <iostream>
template <typename T>
class Vector
{
private:
int m_capacity;
int m_nrOfElements;
T* m_elements;
public:
Vector();
Vector(const Vector& other);
Vector& operator=(const Vector& other);
Vector(Vector&& other);
Vector& operator=(Vector&& other);
Vector(int index, T element);
~Vector();
T& operator[](const int index) const;
T& at(const int index) const;
T& front() const;
T& back() const;
const T* data() const;
void push_back(const T& element);
void pop_back();
bool empty() const;
int size()const;
int capacity() const;
void insert(int index, const T& element);
void erase(int index);
void clear();
};
template<typename T>
inline Vector<T>::Vector()
:m_nrOfElements(0),
m_capacity(5),
m_elements(new T[m_capacity])
{
}
template<typename T>
inline Vector<T>::Vector(const Vector& other)
:m_nrOfElements(other.m_nrOfElements),
m_capacity(other.m_capacity),
m_elements(new T[m_capacity])
{
for (int i = 0; i < other.m_nrOfElements; ++i)
{
m_elements[i] = other.m_elements[i];
}
}
template<typename T>
inline Vector<T>::Vector(int index, T element)
:m_nrOfElements(index),
m_capacity(index +5),
m_elements(new T[m_capacity])
{
for (int i = 0; i < m_nrOfElements; ++i)
{
m_elements[i] = element;
}
}
template<typename T>
inline Vector<T>& Vector<T>::operator=(const Vector& other)
{
if (other.m_nrOfElements > m_nrOfElements)
{
delete[] m_elements;
m_capacity = other.m_capacity;
m_elements = new T[other.m_nrOfElements];
}
for (int i = 0; i < other.m_nrOfElements; i++)
{
m_elements[i] = other.m_elements[i];
}
m_nrOfElements = other.m_nrOfElements;
return *this;
}
template<typename T>
inline Vector<T>::Vector(Vector&& other)
: m_nrOfElements(std::exchange(other.m_nrOfElements, 0)), 
m_capacity(std::exchange(other.m_capacity, 0)), 
m_elements(std::exchange(other.m_elements, nullptr))
{

}
template<typename T>
inline Vector<T>& Vector<T>::operator=(Vector&& other)
{
delete[] m_elements;
m_nrOfElements = other.m_nrOfElements;
m_capacity = other.m_capacity;
for (int i = 0; i < other.size(); i++)
{
m_elements[i] = other.m_elements[i];
}
other.m_elements = nullptr;
other.m_capacity = 0;
other.m_nrOfElements = 0;
return *this;
}
template<typename T>
inline Vector<T>::~Vector()
{
delete[] m_elements;
}
template<typename T>
inline T& Vector<T>::operator[](const int index) const
{
if ((index < 0) || (index >= m_nrOfElements))
{
throw std::exception("Index out of range");
}
return m_elements[index];
}
template<typename T>
inline T& Vector<T>::at(const int index) const
{
if ((index < 0) || (index >= m_nrOfElements))
{
throw std::exception("Index out of range");
}
return m_elements[index];
}
template<typename T>
inline T& Vector<T>::front() const
{   
if (m_nrOfElements == 0)
{
throw std::out_of_range("Index out of range");
}
return m_elements[0];
}
template<typename T>
inline T& Vector<T>::back() const
{
if (m_nrOfElements == 0)
{
throw std::out_of_range("Index out of range");
}
return m_elements[m_nrOfElements - 1];
}
template<typename T>
inline const T* Vector<T>::data() const
{
return m_elements;
}
template<typename T>
inline void Vector<T>::push_back(const T& element)
{
if (m_nrOfElements < m_capacity)
{
m_elements[m_nrOfElements] = element;
m_nrOfElements++;
}
else
{
m_capacity *= 2;
T* newArray = new T[m_capacity];
for (int i = 0; i < m_nrOfElements; ++i)
{
newArray[i] = m_elements[i];
}
newArray[m_nrOfElements] = element;
++m_nrOfElements;
delete[] m_elements;
m_elements = newArray;
push_back(element);
}
}
template<typename T>
inline void Vector<T>::pop_back()
{
if (m_nrOfElements == 0)
{

}
else
{
--m_nrOfElements;
}
}
template<typename T>
inline bool Vector<T>::empty() const
{
return m_nrOfElements == 0;
}
template<typename T>
inline int Vector<T>::size() const
{
return m_nrOfElements;
}
template<typename T>
inline int Vector<T>::capacity() const
{
return m_capacity;
}
template<typename T>
inline void Vector<T>::insert(int index, const T& element)
{
if ((index < 0) || (index >= m_nrOfElements))
{
throw std::exception("Insert index out of range");
}
if (m_nrOfElements != m_capacity)
{
for (int i = m_nrOfElements - 1; i >= index; --i)
{
m_elements[i + 1] = m_elements[i];
}
m_elements[index] = element;
++m_nrOfElements;
}
else
{
m_capacity *= 2;
T* newArray = new T[m_capacity];
for (int i = 0; i < m_nrOfElements; i++)
{
newArray[i] = m_elements[i];
}
delete[] m_elements;
m_elements = newArray;
insert(index, element);
}
}
template<typename T>
inline void Vector<T>::erase(int index)
{
if ((index < 0) || (index >= m_nrOfElements))
{
throw std::exception("Erase index out of range");
}
for (int i = index; i < m_nrOfElements - 1; i++)
{
m_elements[i] = m_elements[i + 1];
}
--m_nrOfElements;
}
template<typename T>
inline void Vector<T>::clear()
{
m_nrOfElements = 0;
}

正如@jo art所评论的,您的move构造函数似乎还可以;但是,移动分配操作符是:

  1. 取消分配m_elements
  2. other.m_elements复制到您刚刚删除的目标指针(无效访问(
  3. other.m_elements设置为nullptr而不首先解除分配(内存泄漏(
delete[] m_elements;
m_nrOfElements = other.m_nrOfElements;
m_capacity = other.m_capacity;
for (int i = 0; i < other.size(); i++)
{
m_elements[i] = other.m_elements[i];
}
other.m_elements = nullptr;
other.m_capacity = 0;
other.m_nrOfElements = 0;

相反:

  1. 取消分配m_elements
  2. other中移动数据,就像在移动构造函数中一样

[演示]

template<typename T>
inline Vector<T>::Vector(Vector&& other)
: m_nrOfElements(std::exchange(other.m_nrOfElements, 0)), 
m_capacity(std::exchange(other.m_capacity, 0)), 
m_elements(std::exchange(other.m_elements, nullptr))
{   
}
template<typename T>
inline Vector<T>& Vector<T>::operator=(Vector&& other)
{
delete[] m_elements;

m_nrOfElements = std::exchange(other.m_nrOfElements, 0);
m_capacity = std::exchange(other.m_capacity, 0);
m_elements = std::exchange(other.m_elements, nullptr);
return *this;
}