当 T=std::string 自定义 Vector C++ 时,为什么我在 push_back(T&&) 上收到 SIGSEGV 错误
Why i get a SIGSEGV error on push_back(T&&) when T=std::string custom Vector C++
#include <algorithm>
#include <utility>
#include <new>
#include <iostream>
template <typename T>
class Vector {
public:
Vector();
~Vector();
void push_back(const T& value);
void push_back(T&& value);
void clear();
std::size_t size() const { return sz; }
std::size_t capacity() const { return cap; }
T& operator[](std::size_t i) { return data[i]; }
const T& operator[](std::size_t i) const { return data[i]; }
private:
T* data;
std::size_t sz;
std::size_t cap;
void p_realloc(std::size_t n);
};
template <typename T>
Vector<T>::Vector()
: sz{}, cap{ 10 }
{
data = (T*)::operator new(cap * sizeof(T));
}
template <typename T>
Vector<T>::~Vector() {
clear();
::operator delete(data, sizeof(T) * cap);
}
template <typename T>
void Vector<T>::p_realloc(std::size_t n) {
T* new_data = (T*)::operator new(n * sizeof(T));
if (n < sz)
sz = n;
for (std::size_t i = 0; i < sz; ++i) {
new_data[i] = std::move(data[i]);
data[i].~T();
}
::operator delete(data, cap * sizeof(T));
data = new_data;
cap = n;
}
template <typename T>
void Vector<T>::clear() {
for (std::size_t i = 0; i < sz; ++i)
data[i].~T();
sz = 0;
}
template <typename T>
void Vector<T>::push_back(const T& value) {
if (sz >= cap)
p_realloc(cap * 1.5);
data[sz++] = value;
}
template <typename T>
void Vector<T>::push_back(T&& value) {
if (sz >= cap)
p_realloc(cap * 1.5);
std::cout << "All good\n"; std::cin.get();
data[sz++] = std::move(value);
}
我正在尝试创建 Vector class 的自定义实现。我已经做了一个,但它不使用 ::operator new 和 delete 以便不调用 constructor/destructor。当 T=std::string 并且我尝试调用 push_back("test_string") 时,我得到一个错误,我不知道为什么。它不应该被隐式转换为 std::string 因此 data[sz++] = std::move(value) 工作吗?
错误不在使用push_back(T&&)。原因在于 data
指向未初始化的内存。
data[sz++] = value;
在未初始化的对象 T 上调用 T::operator=(const T&)
。
data[sz++] = std::move(value);
在未初始化的对象 T 上调用 T::operator=(T&&)
。
您应该使用布置新的
修复两个 push_back
中的作业 data[sz++] =
/* data[sz++] = value; */ new (&data[sz++]) T(value);
/* data[sz++] = std::move(value); */ new (&data[sz++]) T(std::move(value));
#include <algorithm>
#include <utility>
#include <new>
#include <iostream>
template <typename T>
class Vector {
public:
Vector();
~Vector();
void push_back(const T& value);
void push_back(T&& value);
void clear();
std::size_t size() const { return sz; }
std::size_t capacity() const { return cap; }
T& operator[](std::size_t i) { return data[i]; }
const T& operator[](std::size_t i) const { return data[i]; }
private:
T* data;
std::size_t sz;
std::size_t cap;
void p_realloc(std::size_t n);
};
template <typename T>
Vector<T>::Vector()
: sz{}, cap{ 10 }
{
data = (T*)::operator new(cap * sizeof(T));
}
template <typename T>
Vector<T>::~Vector() {
clear();
::operator delete(data, sizeof(T) * cap);
}
template <typename T>
void Vector<T>::p_realloc(std::size_t n) {
T* new_data = (T*)::operator new(n * sizeof(T));
if (n < sz)
sz = n;
for (std::size_t i = 0; i < sz; ++i) {
new_data[i] = std::move(data[i]);
data[i].~T();
}
::operator delete(data, cap * sizeof(T));
data = new_data;
cap = n;
}
template <typename T>
void Vector<T>::clear() {
for (std::size_t i = 0; i < sz; ++i)
data[i].~T();
sz = 0;
}
template <typename T>
void Vector<T>::push_back(const T& value) {
if (sz >= cap)
p_realloc(cap * 1.5);
data[sz++] = value;
}
template <typename T>
void Vector<T>::push_back(T&& value) {
if (sz >= cap)
p_realloc(cap * 1.5);
std::cout << "All good\n"; std::cin.get();
data[sz++] = std::move(value);
}
我正在尝试创建 Vector class 的自定义实现。我已经做了一个,但它不使用 ::operator new 和 delete 以便不调用 constructor/destructor。当 T=std::string 并且我尝试调用 push_back("test_string") 时,我得到一个错误,我不知道为什么。它不应该被隐式转换为 std::string 因此 data[sz++] = std::move(value) 工作吗?
错误不在使用push_back(T&&)。原因在于 data
指向未初始化的内存。
data[sz++] = value;
在未初始化的对象 T 上调用 T::operator=(const T&)
。
data[sz++] = std::move(value);
在未初始化的对象 T 上调用 T::operator=(T&&)
。
您应该使用布置新的
修复两个push_back
中的作业 data[sz++] =
/* data[sz++] = value; */ new (&data[sz++]) T(value);
/* data[sz++] = std::move(value); */ new (&data[sz++]) T(std::move(value));