我可以新的[],然后转换指针,然后删除[]安全与内置类型在C + +? [英] Can I new[], then cast the pointer, then delete[] safely with built-in types in C++?

查看:84
本文介绍了我可以新的[],然后转换指针,然后删除[]安全与内置类型在C + +?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的代码中,我有效地如下:

  wchar_t * buffer = new wchar_t [size] 
//这里的无关代码
delete [] reinterpret_cast< char *>(buffer);

有问题的类型都是内置的,因此它们有微不足道的析构函数。在VC ++中,上面的代码工作allright - new [] 只是分配内存,然后 delete [] / p>

在C ++中可以接受吗?

解决方案

我最初的想法是它是未定义的行为。


5.3.5 / 3:在第二个选项中(删除数组)如果要删除的对象的动态
类型
与其静态类型不同,
行为未定义。 73)


脚注73读取这意味着不能使用类型 void * 的指针删除对象,因为没有类型 void



可以说,你的示例中的对象不是有一个动态类型,因为动态类型在1.3.3提到大多数派生对象,而在1.8 / 4的大多数派生对象的定义是谈论类型的对象所以我一直看:



< blockquote>

5.2.10 / 3:[reinterpret_cast]可能或可能不会产生与原始值

不同的表示


5.3.5 / 2: delete 的操作数的值应为从前一个数组产生的指针值

new-expression


我不知道reinterpret_cast是否会产生相同的指针值输入,还是不输入。可能它由我还没有找到的标准的一些其他位清除。我不会调用这个代码OK,没有找到一些明确的状态,如果你reinterpret_cast一个指针,结果是相同的指针值,因为通过传递给delete []你传递的指针值from new []。


5.2.10 / 7:除了在某些指针类型之间转换和
到其原始类型产生
原始指针值,
的结果这样的指针转换是
未指定


这看起来像是一个坏消息 - 它显然不说,铸造产生相同的价值,只有那对铸件反复,产生相同的价值。这意味着我可以允许单个转换产生不同的值,但它只是暗示,而不是明确的。这是规则的通常的问题,如果标准不陈述行为,则行为是未定义的。只是因为它没有在任何段落中我可以找到使用索引,不意味着它不会在其他地方的状态...



我们知道,在实践中,我们可以将东西转换为unsigned char *,以检查其字节,或void *使用memcpy复制POD,因此必须保证一些转义来创建别名。你可能会认为,如果你的实现确实使用某些转换创建了别名,那么你传递的是从新的[]中获得的相同的值。但我仍然不确定这是不够好删除[]。我想我缺少一些重要的东西。


In my code I have effectively the following:

wchar_t* buffer = new wchar_t[size];
// bonus irrelevant code here
delete[] reinterpret_cast<char*>( buffer );

Types in question are all built-in and so they have trivial destructors. In VC++ the code above works allright - new[] just allocates memory, then delete[] just frees it.

Is it acceptable in C++? Is it undefined behaviour?

解决方案

My initial thought was that it is undefined behavior.

5.3.5/3: "In the second alternative (delete array) if the dynamic type of the object to be deleted differs from its static type, the behavior is undefined.73).

Footnote 73 reads, "This implies that an object cannot be deleted using a pointer of type void* because there are no objects of type void".

Arguably the object in your example doesn't have a dynamic type, since the definition of "dynamic type" at 1.3.3 mentions "most derived object", and the definition of "most derived object" at 1.8/4 is talking about objects of class type. So I kept looking:

5.2.10/3: "[reinterpret_cast] might, or might not, produce a representation different from the original value"

5.3.5/2: "The value of the operand of delete shall be the pointer value which resulted from a previous array new-expression".

I'm not sure whether a reinterpret_cast results in the same pointer value as was input, or not. Possibly it's cleared up by some other bit of the standard which I haven't found yet. I would not call this code "OK" without finding something to definitively state that if you reinterpret_cast a pointer, the result is the same "pointer value" as before, so that by passing it to delete[] you are passing "the pointer value" from new[].

5.2.10/7: "Except that casting [between certain pointer types] and back to its original type yields the original pointer value, the result of such a pointer conversion is unspecified".

This looks like bad news to me - it conspicuously doesn't say that the cast yields the same value, only that the pair of casts over and back, yields the same value. This suggests to me that the single cast is allowed to yield a different value, but it is only suggestive, not explicit. This is the usual problem with the rule that "if the standard doesn't state the behavior, then the behavior is undefined". Just because it doesn't state it in any of the paragraphs I can find using the index, doesn't mean it doesn't state it somewhere else...

We know that in practice we can cast things to unsigned char* in order to inspect their bytes, or void* to copy PODs using memcpy, so there must be some casts guaranteed to create aliases. You might think that if your implementation does create aliases with certain casts, then you're passing in the "same value" you got from new[]. But I'm still not sure that's good enough for delete[]. I think I'm missing something important.

这篇关于我可以新的[],然后转换指针,然后删除[]安全与内置类型在C + +?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆