C ++无法删除动态大小的成对数组
C++ Trouble deleting dynamic sized array of pairs
我在删除 m_Array 时遇到很多问题。程序在执行清理部分时最后会出现段错误。我有两个 class A 对象,它们在 m_Array 中具有不同的数据,并且在程序中的某个时刻,一个对象的数据开始 "wrap around" 进入另一个数组,导致数据不正确。
T 代表我的模板化数据类型。
还有一个class B,它只是创建了两个class A对象
公开声明在class 声明一个赞:
template <typename T> class A
{
public:
pair<T, int> *m_Array; // Array of type pair
A(int size=1); // constructor
~A(); // A destructor
// ... all other definitions //
};
在 class A 的构造函数定义中定义如下:
template <typename T>
A<T>::A(int size) {
// Set array size
m_Array = new pair<T, int>[size];
// Initialize values
for (int i = 0; i < size; i++) {
m_Array[i] = make_pair(-1, -1);
}
//... other things defined and initialized...//
}
在 class A 的析构函数中:
template <typename T>
A<T>::~A() {
delete [] m_Array; // Not working as it should
}
重载赋值运算符
template <typename T>
const A<T>& A<T>::operator=(const A<T>& rhs) {
m_AArraySize = rhs.m_AArraySize;
m_currASize = rhs.m_currASize;
for (int i = 0; i < m_currASize; i++) {
m_Array[i].first = rhs.m_Array[i].first;
m_Array[i].second = rhs.m_Array[i].second;
}
_ptr = rhs._ptr;
return *this;
}
复制构造函数
template <typename T>
A<T>::A(const A<T>& other) {
m_AArraySize = other.m_AArraySize;
m_AHeapSize = other.m_AHeapSize;
for (int i = 0; i < m_currASize; i++) {
m_Array[i].first = other.m_Array[i].first;
m_Array[i].second = other.m_Array[i].second;
}
_ptr = other._ptr;
}
Class B 声明
template <typename T> class B{
public:
//B constructor
B(int size);
int m_currBSize; // spots used in array
int m_BSize; // size of array
A <T> oneAHolder;
A <T> twoAHolder;
};
Class B 构造函数
template <typename T>
b<T>::b(int size){
A<T>(size);
m_BArraySize = size;
m_currBSize = 1;
// Create two A objects
A<T> oneA(size);
A<T> twoA(size);
// oneA and twoA go out of scope
oneAHolder = oneA;
twoAHolder = twoA;
}
在我的主要功能中,我所做的就是创建一个 class B 对象,并使用它的插入函数将数据插入到它的两个 A 对象中。
我尝试了几种不同的方法来从数组中删除数据,并阻止数据溢出到另一个数组中,但都无济于事。
感谢任何帮助!
P.S.: 请不要"Just use std::vector"
编辑:添加了更多我的代码
根据您 post 编写的代码,您的赋值运算符有两个问题:
1) 赋值运算符泄漏内存,因为您未能释放旧内存。
2) 除非 this->m_Array
已经足够大,否则您将覆盖 for
循环中的内存,因为 this->m_Array
是比 rhs.m_Array
.[=21 更小的缓冲区=]
您可以简单地使用 copy/swap idiom.
而不是所有这些错误代码
#include <algorithm>
//...
template <typename T>
A<T>& A<T>::operator=(const A<T>& rhs)
{
A<T> temp(rhs);
std::swap(temp.m_AArraySize, m_AArraySize);
std::swap(temp.m_currASize, m_currASize);
std::swap(temp.m_Array, m_Array);
std::swap(temp._ptr, _ptr);
return *this;
}
如果您编写了 correct 不间接调用赋值运算符的复制构造函数和 correct 析构函数,则此方法有效。如果其中任何一个功能出现故障,上述方法将不起作用。
假设复制构造函数和析构函数没有错误,以这种方式编写赋值运算符可以避免重写复制构造函数的代码,因为您只是在重用它。
如果 A
中有更多的成员变量,但您没有在 post 中指定,它们也都需要交换。
简而言之,这基本上只是复制 rhs
并将 this
中的所有旧数据与 temp
交换。然后 temp
最后用旧数据消失。
我在删除 m_Array 时遇到很多问题。程序在执行清理部分时最后会出现段错误。我有两个 class A 对象,它们在 m_Array 中具有不同的数据,并且在程序中的某个时刻,一个对象的数据开始 "wrap around" 进入另一个数组,导致数据不正确。 T 代表我的模板化数据类型。
还有一个class B,它只是创建了两个class A对象
公开声明在class 声明一个赞:
template <typename T> class A
{
public:
pair<T, int> *m_Array; // Array of type pair
A(int size=1); // constructor
~A(); // A destructor
// ... all other definitions //
};
在 class A 的构造函数定义中定义如下:
template <typename T>
A<T>::A(int size) {
// Set array size
m_Array = new pair<T, int>[size];
// Initialize values
for (int i = 0; i < size; i++) {
m_Array[i] = make_pair(-1, -1);
}
//... other things defined and initialized...//
}
在 class A 的析构函数中:
template <typename T>
A<T>::~A() {
delete [] m_Array; // Not working as it should
}
重载赋值运算符
template <typename T>
const A<T>& A<T>::operator=(const A<T>& rhs) {
m_AArraySize = rhs.m_AArraySize;
m_currASize = rhs.m_currASize;
for (int i = 0; i < m_currASize; i++) {
m_Array[i].first = rhs.m_Array[i].first;
m_Array[i].second = rhs.m_Array[i].second;
}
_ptr = rhs._ptr;
return *this;
}
复制构造函数
template <typename T>
A<T>::A(const A<T>& other) {
m_AArraySize = other.m_AArraySize;
m_AHeapSize = other.m_AHeapSize;
for (int i = 0; i < m_currASize; i++) {
m_Array[i].first = other.m_Array[i].first;
m_Array[i].second = other.m_Array[i].second;
}
_ptr = other._ptr;
}
Class B 声明
template <typename T> class B{
public:
//B constructor
B(int size);
int m_currBSize; // spots used in array
int m_BSize; // size of array
A <T> oneAHolder;
A <T> twoAHolder;
};
Class B 构造函数
template <typename T>
b<T>::b(int size){
A<T>(size);
m_BArraySize = size;
m_currBSize = 1;
// Create two A objects
A<T> oneA(size);
A<T> twoA(size);
// oneA and twoA go out of scope
oneAHolder = oneA;
twoAHolder = twoA;
}
在我的主要功能中,我所做的就是创建一个 class B 对象,并使用它的插入函数将数据插入到它的两个 A 对象中。
我尝试了几种不同的方法来从数组中删除数据,并阻止数据溢出到另一个数组中,但都无济于事。
感谢任何帮助!
P.S.: 请不要"Just use std::vector"
编辑:添加了更多我的代码
根据您 post 编写的代码,您的赋值运算符有两个问题:
1) 赋值运算符泄漏内存,因为您未能释放旧内存。
2) 除非 this->m_Array
已经足够大,否则您将覆盖 for
循环中的内存,因为 this->m_Array
是比 rhs.m_Array
.[=21 更小的缓冲区=]
您可以简单地使用 copy/swap idiom.
而不是所有这些错误代码#include <algorithm>
//...
template <typename T>
A<T>& A<T>::operator=(const A<T>& rhs)
{
A<T> temp(rhs);
std::swap(temp.m_AArraySize, m_AArraySize);
std::swap(temp.m_currASize, m_currASize);
std::swap(temp.m_Array, m_Array);
std::swap(temp._ptr, _ptr);
return *this;
}
如果您编写了 correct 不间接调用赋值运算符的复制构造函数和 correct 析构函数,则此方法有效。如果其中任何一个功能出现故障,上述方法将不起作用。
假设复制构造函数和析构函数没有错误,以这种方式编写赋值运算符可以避免重写复制构造函数的代码,因为您只是在重用它。
如果 A
中有更多的成员变量,但您没有在 post 中指定,它们也都需要交换。
简而言之,这基本上只是复制 rhs
并将 this
中的所有旧数据与 temp
交换。然后 temp
最后用旧数据消失。