为什么不保证memcpy对非POD类型是安全的? [英] Why isn't memcpy guaranteed to be safe for non-POD types?
问题描述
我从SO上张贴的几个问题中阅读了这一段。
I read about this paragraph from a few questions posted on SO.
我不清楚为什么 memcpy
不能保证对非POD类型是安全的。我的理解是 memcpy
只是一个位智能的副本。
I can't quite figure out why memcpy
isn't guaranteed to be safe for a non-POD type. My understanding is that memcpy
is just a bit-wise copy.
以下是标准的报价
对于任何对象基本类子对象)
POD
类型T
,无论对象是否保存类型T
,
组成对象的底层字节(1.7)可以复制到char
或unsigned char
.41)如果char
或unsigned char数组的内容
被复制回对象,对象将随后保持其原始的
值。
For any object (other than a base-class subobject) of
POD
typeT
, whether or not the object holds a valid value of typeT
, the underlying bytes (1.7) making up the object can be copied into an array ofchar
orunsigned char
.41) If the content of the array ofchar
orunsigned char
is copied back into the object, the object shall subsequently hold its original value.
# define N sizeof (T)
char buf[N];
T obj ; // obj initialized to its original value
std :: memcpy (buf , & obj , N); // between these two calls to std::memcpy,
// obj might be modified
std :: memcpy (& obj , buf , N); // at this point, each subobject of obj of
// scalar type holds its original value
推荐答案
尝试逐位复制 std :: shared_ptr<>
。
你会遇到这个问题,任何类的副本构造函数除了一个bit-明智的副本。在 std :: shared_ptr<>
的情况下,它将复制指针,但不会增加引用计数,所以你最终会释放共享对象和它的引用计数提前,然后在复制的 shared_ptr
尝试减少释放的引用计数时冒出。
You'll encounter this problem with any class whose copy constructor does something other than a bit-wise copy. In the case of std::shared_ptr<>
, it'll copy the pointer but won't increment the reference count, so you'll end up freeing the shared object and its reference count early, and then blowing up when the copied shared_ptr
tries to decrement the freed reference count.
更新:有人指出,这并不完全回答这个问题,这是公平的,因为我主要讨论将shared_ptr复制到shared_ptr的想法,不是shared_ptr到char []和回来。
UPDATE: It was pointed out that this doesn't quite answer the question, which is fair, since I mainly addressed the idea of copying shared_ptr to shared_ptr, not shared_ptr to char[] and back again. However, the principle still holds.
如果按位复制一个shared_ptr到char [],请为shared_ptr指定一个不同的值,然后复制char []返回,最终结果可能是泄漏一个对象并且双删除另一个对象,即UB。
If you bit-wise copy a shared_ptr to a char[], assign a different value to the shared_ptr, then copy the char[] back over, the end result may be to leak one object and double-delete another, i.e., UB.
POD也可能发生同样的情况,但这将是一个程序逻辑中的错误。只要程序理解并适应这样的事件,逐位复制回到修改的shared_ptr的POD等价物将是完全有效的。这样做std :: shared_ptr通常不会工作。
The same might happen with a POD, but that would be a bug in the program logic. Bit-wise copying back into the POD equivalent of a modified shared_ptr would be perfectly valid as long as the program understands and accommodates such an event. Doing so for a std::shared_ptr generally won't work.
这篇关于为什么不保证memcpy对非POD类型是安全的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!