使用初始化列表时发生堆损坏错误
Heap corruption error occurs when using initializer list
我有一个 class,我在堆上创建了一个数组。后来我增加了这个数组的大小。当构造 class 时,我初始化数组。如果我在初始化列表中这样做,我会在增加数组大小时得到 'heap corruption error',但如果我不使用初始化列表,它不会发生。
请注意,我还没有用这两个构造函数创建 class,但当时只创建了一个。
为什么使用initailizer list没有达到预期效果?
template <typename T>
class Vector {
public:
Vector() noexcept;
void push_back(const T& t);
private:
T* m_arr;
unsigned int m_size;
unsigned int m_capacity;
void realloc();
};
template<typename T>
inline Vector<T>::Vector() noexcept
: m_size(0), m_capacity(1) {
m_arr = new T[m_capacity];
// realloc() works fine with this constructor.
}
template<typename T>
inline Vector<T>::Vector() noexcept
: m_size(0), m_capacity(1), m_arr(new T[m_capacity]) {
// Error occurs in realloc() with this constructor.
}
template<typename T>
inline void Vector<T>::push_back(const T& t) {
if (m_size == m_capacity) {
m_capacity <<= 1;
realloc();
}
m_arr[m_size] = t;
++m_size;
}
template<typename T>
inline void Vector<T>::realloc() {
T* newArr = new T[m_capacity];
memcpy(newArr, m_arr, m_size * sizeof(T));
delete[] m_arr; // Error occurs here with initializer list constructor.
m_arr = newArr;
}
代码崩溃的示例用法:
int main() {
Vector vec;
vec.push_back(0);
vec.push_back(0); // Crashes here
vec.push_back(0);
return 0;
}
template<typename T>
inline Vector<T>::Vector() noexcept
: m_size(0), m_capacity(1), m_arr(new T[m_capacity]) {}
在于成员初始值设定项列表的工作方式 (https://en.cppreference.com/w/cpp/language/initializer_list)。在标题为 "Initialization order" 的部分中,它指出:
non-static data members are initialized in order of declaration in the class definition
这意味着由于您的 class 定义 m_arr(new T[m_capacity])
在 之前执行 m_capacity(1)
这意味着 new[]
使用一个未初始化的变量,从而导致 未定义的行为