删除[]具有不同类型的未定义行为?
delete[] with different type undefined behaviour?
我想知道这是否是未定义的行为:
#include <stdint.h>
int main() {
auto* p = new uint8_t[32];
float* c = reinterpret_cast<float*>(p);
delete[] c;
}
在标准中 有
否则,行为未定义。在第二种备选方案(删除数组(中,删除的操作数的值可以是空指针值,也可以是前一个数组 new-expression 产生的指针值。79 否则,行为是未定义的。[ 注意:这意味着删除表达式的语法必须与 new 分配的对象类型匹配,而不是与 new 表达式的语法匹配。 — 尾注 ]
所以解释有点不清楚的短语
这意味着 delete-expression 的语法必须与 new 分配的对象类型匹配,而不是与 new 表达式的语法匹配
我可以说以上是未定义的行为,对吗?
是的,行为是未定义的。
传递给delete[]
的指针必须与您从new[]
返回的指针的类型相同。
注意,对于delete
和new
,提交给delete
的指针允许通过多态性关联。
是的,确实是未定义行为中的代码。措辞意味着当您将其重写为
int main() {
void* p;
{
using T = uint8_t;
p = new T [32];
}
{
using T = float;
T* c = reinterpret_cast<float*>(p);
delete[] c; // The behaviour is still undefined.
}
}
IOW,类型确实必须完全匹配,而不仅仅是名称。
如果p
具有与new[]
返回的类型不同的类型,则调用delete[] p;
是未定义的行为。
特别是:
struct Base { virtual ~Base() = default; };
struct Derived: Base { int a; };
int main() {
Base* p = new Derived[5];
delete[] p;
}
也是未定义的行为。
@Justin 在评论中提供了相关的标准报价,请参阅此处:
5.3.5 [删除]
(3( 在第一种备选方案(删除对象(中,如果要删除的对象的静态类型与其动态类型不同,则静态类型应是要删除的对象的动态类型的基类,并且静态类型应具有虚拟析构函数或行为未定义。在第二种备选方案(删除数组(中,如果要删除的对象的动态类型与其静态类型不同,则行为未定义。
请注意,在我强调的删除数组案例中没有提供多态关系;与删除对象情况相反。
相关文章:
- 交换未定义数据类型中的字节顺序
- 类型特征检查 CRTP 派生,在基类中,问题是未定义的类型
- 派生类错误:未定义的类型
- 未分配返回未定义对象类型引用的 C++ 函数的返回值时会发生什么情况
- 在从抽象类继承的模板类中正确使用未定义的类型
- 子类中使用了不完整的指针-错误:使用了未定义的类型
- C++模板,在编译时解析未定义的类型
- 错误 C2679:二进制"=":未定义采用类型右侧操作数的运算符
- 如何让 MS C++编译器识别 #include 中未定义的类型
- 提升序列化提供未定义的类型'boost::STATIC_ASSERTION_FAILURE'
- C++错误C2027:使用未定义的类型'第二'(朋友班)
- 在 c++ 中使用字符串时出错。error C2679:二进制'<<':未定义采用类型为"类"的右操作数的运算符
- 错误C2027:使用未定义的类型-如何声明类
- ostringstream是一个未定义的类型
- 使用未定义的类型c++,类
- 在对象文件中具有未定义符号类型的程序如何在没有任何链接器错误的情况下进行编译"U"?
- C++错误:使用了未定义的类型
- 错误C2027:在多个文件中使用未定义的类型
- 未定义的类型错误,即使有前向声明
- 如何通过未定义的类型定义元函数