我有一个数组,它通过一个函数传递并分配给一个类成员,它是一个指针。
class ClassA{
unsigned char * pointerToArray;
ClassA(unsigned char array[]){
pointerToArray = array;
}
~ClassA(){
//what to do here
}
};
现在我有了第二个使用这个的类
class ClassB {
std::list<ClassA> classAcollection;
void firstFunction(){
for(int i = 0; i < 5; i++){
unsigned char buffer[3000];
somePopulationFunction(&buffer);
classAcollection.push_back(ClassA(buffer);
}
}
void secondFuncion(){
std::list<ClassA>::iterator it;
for(it = classAcollection.begin(); it != classAcollection.end(); it++)
{
classAcollection.erase(it);
}
}
};
我的问题是如何确保每次调用 classAcollection.erase(it) 时删除 pointerToArray。
我无法在 ClassA 析构函数中添加删除调用,因为出现以下错误: 未分配正在释放的指针
最佳答案
你的第一句话已经说明了所有的困惑:
Hi, I have an array that is passed via a function and assigned to a class member which is a pointer.
你不能“传递一个数组”。您可以将指向数组或数组元素的指针或引用传递给函数。 ClassA 的构造函数中的参数array 的类型实际上是一个指针类型。这些 C 规则已经让足够多的人感到困惑。请务必查看优秀的数组/指针教程。
这是您的代码中真正发生的事情:
- 您在第一个函数中创建一个具有自动存储持续时间的数组,
- 你用数据填充它。
- 您将指向数组第一个元素的指针传递给构造函数ClassA::ClassA
- 迭代完成,数组不复存在,步骤 1-3 再重复 4 次
问题:所有 ClassA 对象都有一个无效的指针成员,因为它们引用的所有数组现在都消失了。
如果您希望这些数组的生命周期超过其作用域,则需要动态分配。您可以动态分配数组并将“所有权转移”给ClassA 对象。我们所说的“所有权”通常是指管理和删除数组的责任。这是可能的,其他答案向您展示了如何解决这个问题。但它们实际上是不完整的。你看,如果你想要一个类对象来管理像内存这样的资源,你要做的不仅仅是提供一个析构函数。您还必须注意复制。这意味着复制构造函数和赋值运算符。因为您不仅要创建类 ClassA 的对象,而且要将它用作列表的 push_back 函数的参数,列表将生成它的拷贝 并存储/管理该拷贝。因此,如果您仍然希望通过存储一个简单的(哑)指针使 ClassA 正确管理缓冲区,您必须编写复制构造函数、赋值运算符和析构函数,否则它们将由编译器生成。编译器生成的只是按成员方式复制。我猜你不希望两个不同的 ClassA 对象共享同一个缓冲区,对吧?
除了处理原始指针,您还可以使用 vector 作为 ClassA 成员:
class ClassA
{
std::vector<unsigned char> buffer;
public:
ClassA(unsigned char const* begin, unsigned char const* end)
: buffer(begin,end)
{}
};
:
:
void firstFunction()
{
for(int i = 0; i < 5; i++) {
unsigned char buffer[3000];
somePopulationFunction(&buffer);
classAcollection.push_back(ClassA(buffer+0,buffer+3000));
}
}
之所以可行,是因为 std::vector 的行为不像指针。如果你复制一个 vector ,拷贝将管理它自己的元素。没有分享。在这方面, vector 更像是一个普通的 int 或 double。它通常是根据指针来实现的。但感觉像是“常规值类型”。
我们在这里无能为力。如果您想将 ClassA 对象放入列表中,ClassA 必须是可复制的。因此,很难避免任何复制,同时避免在 ClassA 对象之间共享缓冲区。
在 C++0x(即将到来的 C++ 标准的代号)中,您将能够这样做:
class ClassA
{
std::vector<unsigned char> buffer;
public:
ClassA(unsigned char const* begin, unsigned char const* end)
: buffer(begin,end)
{}
ClassA(ClassA const&) = default;
ClassA(ClassA &&) = default;
ClassA& operator=(ClassA const&) = default;
ClassA& operator=(ClassA &&) = default;
};
它将创建一个可复制和“可移动”的类。支持移动的类通常可以非常有效地从函数传递到函数。在您的示例中,ClassA 对象是一个临时对象。因此,它可以快速移动到列表中,而无需任何不必要的缓冲区对象复制。但这只是逗你玩的。 C++0x 尚未正式发布。
关于c++ - 指向数组删除的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3923136/