尝试用C 中的空地址(而非null)删除数组指针
Trying to delete array pointer with empty address (not NULL) in C++
我创建了一个包含像素强度值数组的类。复制此类时,我会收到一个错误,就好像我试图删除非分配的数组一样。由于我敢肯定,我没有设置指针的尖锐地址,指向班级的创建和副本之间的任何内容,因此我对指针的地址与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
}
- QML:修改在不同QML文件(而非main.QML)中定义的子对象的属性
- 为x86而非x64编译时出错
- 为什么 nlohmann/json 序列化 "null" 而不是在 double 上"0"?
- 打印空指针时,std::cout 可以打印 "NULL" 而不是 0 吗?
- cpp 数组 - 分配常量索引有效,而非常量索引不起作用
- C++ 由于类析构函数中的指针设置为 NULL 而导致的内存泄漏
- 与类而非对象绑定的可变变量
- 在C 中本地声明隐藏的封闭范围(而非全局)中访问变量
- 从C++二进制搜索树中删除一个节点(类而非结构)
- 尝试用C 中的空地址(而非null)删除数组指针
- C++将 NULL 和非 NULL 值转换为指针
- C 链接列表仅在GNU/Linux而非Windows中导致分割故障
- 为什么 GetProcessImageFileName 返回 null 而不是进程的地址
- Qt3D中QGLView(而非QGLWidget)上的过度绘制和后期渲染效果
- 在mac上用c++编写独立游戏程序需要哪些软件(从软件功能而非名称来看)
- C++ "triangle"(而非钻石)继承
- 将字符串(字符*而非字符串类型)转换为整数
- 返回 NULL 而不是 std::string C++
- 什么是 NULL 的非指针等效项
- 如何检索具有键而非标量的映射节点