尝试用C 中的空地址(而非null)删除数组指针

Trying to delete array pointer with empty address (not NULL) in C++

本文关键字:null 而非 删除 指针 数组 空地址      更新时间:2023-10-16

我创建了一个包含像素强度值数组的类。复制此类时,我会收到一个错误,就好像我试图删除非分配的数组一样。由于我敢肯定,我没有设置指针的尖锐地址,指向班级的创建和副本之间的任何内容,因此我对指针的地址与NULL的不同是如此神秘。如何检查空尖的地址?

data_ == reinterpret_cast<const unsigned char *>("")

不起作用。

类:

template<class T> class PixelArray {
public:
    int width_, height_;
    int size_;
    T* data_;
    PixelArray() {
        data_ = NULL;
    };
    ~PixelArray() {
        if (data_ != NULL)
            delete[] data_;
        data_ = NULL;
    };
    PixelArray(const PixelArray& other)
    {
        if (data_)
            delete[] data_;  // ERROR BEING THROWN HERE
        data_ = NULL:
        data_ = new T[other.size_];
        size_ = other.size_;
        width_ = other.width_;
        height_ = other.height_;
        std::copy(other.data_, other.data_ + other.size_, data_);
    }        
};

问题:

破裂时变量的状态

在复制构建器中尚未初始化成员变量,delete[]没有任何内容。

相反,成员变量data_将没有一个不确定的值,并且它似乎是随机的,并且很可能不等于零指针,这意味着您将拥有不确定的行为

最简单的解决方案?不要使用非初始化指针delete[]


复制构建器就像其他任何构造函数一样,在创建实例时称为。没有其他构造函数用于复制构建,只有复制构建器。

    if (data_)
        delete[] data_;  // ERROR BEING THROWN HERE

数据尚未初始化,您在复制构造函数中;默认的构造函数并未为您拨打。

删除这2行将删除您对非初始化变量的访问并解决您的问题。

正如马科斯在评论中所说的那样 - 您可以使用智能指针

更好地解决问题

试图用空地址删除数组指针(而不是null)

没有这样的东西。有空指针(值0),并且指针有非零值。非无效指针可能会或可能不会指向有效的对象。也许"空"是指尖头对象无效。

如何检查空尖的地址?

没有办法检查指向对象是否有效。您必须确保指针始终指向有效的对象,只要您使用它。


只有2个情况可以在指针上调用delete[]

  • 这是null
  • 指针由new[]返回,并且指针以前尚未删除。

在其他情况下删除指针会导致UB。指针不符合这些要求的情况:

  • 指针从未初始化。示例:

    T* data_;
    
  • 指针被初始化为new[]未返回的值。示例:

    T* data_ = new T;
    T* data_ = reinterpret_cast<const unsigned char *>("");
    
  • 指针由new[]返回,但以前已删除。这称为悬空指针。

    T* data_ = new T[10];
    delete[] data_;
    // data_ is a danging pointer here
    

PixelArray(const PixelArray& other)
{
    if (data_)
        delete[] data_;  // ERROR BEING THROWN HERE

对我来说,这一切都是如此神秘

指针尚未初始化,因此未指定其值。仅当您将其初始化或分配给null时才为null。

您正在删除一个非初始化的指针,因此该程序的行为不确定。

ps。检查data_是否不是零是多余的,因为删除无效指针是安全的。


直接问题

soution:不要尝试删除非初始化的指针 - 删除复制构造函数的前两行。解决其他问题的解决方案:使用std::vector。这将修复您的错误并大大简化代码。

[我不使用std::vector],因为在代码的其他部分中,I通过数组迭代了四个指针,将其尖锐的地址通过一个循环的每个周期提高了一个。

std::vector不能阻止您这样做。

,但我想如果矢量迭代器不能降低性能(在这种情况下是重要的)。

这也可以使用迭代器来完成,我不知道为什么他们比指针的性能要低。

您不必在复制构造函数中删除[] data_,因为data_尚未分配。

我认为您试图通过DELETE []数据在分配运算符函数中完成。

PointerArray& operator=(const PointerArray& other) {
    if (data_){delete[] data_;}
    //allocate data_ and copy the contents from other.data_
    //rest of the assignment code here
}