c++ - 指向数组删除的指针

标签 c++ arrays pointers free

我有一个数组,它通过一个函数传递并分配给一个类成员,它是一个指针。

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/

相关文章:

c++ - Windows .lib 文件是否有一些等效的 GNU 二进制文件描述符 (BFD)?

c++ - Eigen3:定义可变大小矩阵

arrays - 快速 array.removeAtIndex 错误

pointers - 在 C 中将指针复制到指针 'contents'

c++ - 无法解决cocos2dx中的 "error: candidate is:"

C++ CMD 输入和 exe

javascript - 如何在不使用过滤方法的情况下根据两个数组的出现次数来比较它们?

python - 如何在 Python Pandas 中的数组、列表或数据帧中的每个单个数字元素的末尾 append 1?

c - C中const指针的初始化

c - 通过引用传入二维数组