为什么不保证memcpy对非POD类型是安全的? [英] Why isn't memcpy guaranteed to be safe for non-POD types?

查看:182
本文介绍了为什么不保证memcpy对非POD类型是安全的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从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 type T, whether or not the object holds a valid value of type T, the underlying bytes (1.7) making up the object can be copied into an array of char or unsigned char.41) If the content of the array of char or unsigned 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屋!

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