为什么在 C++ 中使用 Delete[] 会出现 Trace/Breakpoint 错误?
Why is there a Trace/Breakpoint error using Delete[] in c++?
我目前正在制作 "vector" class。
template <typename T>
class Vectors{
private:
int size_;
public:
int size_;
T *elements;
Vector(){
size_=0;
T *elements=new T[size_];
}
Vector(int size){
size_=size;
T *elements=new T[size_];
}
void push_back(T amaze){
//make new temporary pointer;
T *Temp=new T[size_+1];
size_=size_+1;
for(int i=0;i<size_-1;i++)
{
*(Temp+i)=*(elements+i);
}
delete[] elements; //Error occurs here
elements=NULL;
elements=Temp;
*(elements+size_-1)=amaze;
}
}
调试器运行后,我发现当程序到达delete[]元素时有一个trace/breakpoints陷阱。
为什么会出现这个错误?
您的构造函数未向 class elements
成员分配任何内容。他们正在分配给同名的局部变量,隐藏 class 成员。因此,当 push_back()
尝试 delete[]
时,class 成员仍未初始化。
改变
T *elements=new T[size_];
到
elements=new T[size_];
另请注意,您的 class 不遵循 Rule of 3/5/0,因为它缺少析构函数、复制构造函数和复制赋值运算符。并且它声明了 size_
成员两次,应该编译失败。
试试这个:
template <typename T>
class Vector{
private:
int size_;
int count_;
T *elements;
public:
Vector(){
size_ = 0;
count_ = 0;
elements = new T[size_];
}
Vector(int size){
size_ = size;
count_ = 0;
elements = new T[size_];
}
Vector(const Vector &v){
size_ = v.size_;
count = v.count_;
elements = new T[size_];
for(int i = 0; i < count_; ++i) {
elements[i] = v.elements[i];
}
}
~Vector() {
delete[] elements;
}
void push_back(T amaze){
if (count_ == size_) {
T *Temp = new T[size_ * 2];
for(int i = 0; i < count_; ++i) {
Temp[i] = elements[i];
}
delete[] elements;
elements = Temp;
size_ *= 2;
}
elements[count_]= amaze;
++count_;
}
void swap(Vector &other) {
std::swap(elements, other.elements);
std::swap(size_, other.size_);
std::swap(count_, other.count_);
}
Vector& operator=(const Vector &v) {
if (&v != this) {
Vector(v).swap(*this);
}
return *this;
}
};
启用警告,你会看到你不是在初始化elements
成员而是一个变量:
T *elements=new T[size_];
所以当你删除它们时,你基本上是在试图删除一个从未分配过且指向任何地方的损坏指针。这实际上会使程序崩溃。
顺便说一下,你应该 post 你的实际代码是 运行,因为目前你的 class 名字是 Vectors
,复数;但构造函数称为 Vector
。一个合适的构造函数将使用初始化列表并且将是 explicit
:
explicit Vector(std::size_t size)
: size_(size), elements_(new T[size_])
{
}
默认构造函数不应尝试分配大小为 0 的数组。只需将 elements
保持为 nullptr
。
我目前正在制作 "vector" class。
template <typename T>
class Vectors{
private:
int size_;
public:
int size_;
T *elements;
Vector(){
size_=0;
T *elements=new T[size_];
}
Vector(int size){
size_=size;
T *elements=new T[size_];
}
void push_back(T amaze){
//make new temporary pointer;
T *Temp=new T[size_+1];
size_=size_+1;
for(int i=0;i<size_-1;i++)
{
*(Temp+i)=*(elements+i);
}
delete[] elements; //Error occurs here
elements=NULL;
elements=Temp;
*(elements+size_-1)=amaze;
}
}
调试器运行后,我发现当程序到达delete[]元素时有一个trace/breakpoints陷阱。
为什么会出现这个错误?
您的构造函数未向 class elements
成员分配任何内容。他们正在分配给同名的局部变量,隐藏 class 成员。因此,当 push_back()
尝试 delete[]
时,class 成员仍未初始化。
改变
T *elements=new T[size_];
到
elements=new T[size_];
另请注意,您的 class 不遵循 Rule of 3/5/0,因为它缺少析构函数、复制构造函数和复制赋值运算符。并且它声明了 size_
成员两次,应该编译失败。
试试这个:
template <typename T>
class Vector{
private:
int size_;
int count_;
T *elements;
public:
Vector(){
size_ = 0;
count_ = 0;
elements = new T[size_];
}
Vector(int size){
size_ = size;
count_ = 0;
elements = new T[size_];
}
Vector(const Vector &v){
size_ = v.size_;
count = v.count_;
elements = new T[size_];
for(int i = 0; i < count_; ++i) {
elements[i] = v.elements[i];
}
}
~Vector() {
delete[] elements;
}
void push_back(T amaze){
if (count_ == size_) {
T *Temp = new T[size_ * 2];
for(int i = 0; i < count_; ++i) {
Temp[i] = elements[i];
}
delete[] elements;
elements = Temp;
size_ *= 2;
}
elements[count_]= amaze;
++count_;
}
void swap(Vector &other) {
std::swap(elements, other.elements);
std::swap(size_, other.size_);
std::swap(count_, other.count_);
}
Vector& operator=(const Vector &v) {
if (&v != this) {
Vector(v).swap(*this);
}
return *this;
}
};
启用警告,你会看到你不是在初始化elements
成员而是一个变量:
T *elements=new T[size_];
所以当你删除它们时,你基本上是在试图删除一个从未分配过且指向任何地方的损坏指针。这实际上会使程序崩溃。
顺便说一下,你应该 post 你的实际代码是 运行,因为目前你的 class 名字是 Vectors
,复数;但构造函数称为 Vector
。一个合适的构造函数将使用初始化列表并且将是 explicit
:
explicit Vector(std::size_t size)
: size_(size), elements_(new T[size_])
{
}
默认构造函数不应尝试分配大小为 0 的数组。只需将 elements
保持为 nullptr
。