memmove、memcpy 和新的
我正在制作一个简单的字节缓冲区,将其数据存储在用 new 获取的 char 数组中,我只是想知道如果在用 new 获取的内存上使用 memcpy 和 memmove 函数是否会给我带来任何奇怪的东西,或者您是否建议做任何事情?
I am making a simple byte buffer that stores its data in a char array acquired with new and I was just wondering if the memcpy and memmove functions would give me anything weird if used on memory acquired with new or is there anything you would recommend doing instead?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
使用
memcpy()
/memmove()
应该可以很好地处理此类数据。一般来说,您可以在任何 POD 类型上安全地使用它们。Using
memcpy()
/memmove()
should work fine on that kind of data. In general, you can use them safely on any POD type.不,他们很好。
new
和malloc()
只是获取堆上内存的两种不同方式(实际上它们完全相同,因为new
使用在大多数实现中,malloc()
在底层)。一旦您手中有一个有效的char*
变量(由new
、malloc()
或在堆栈上分配),它就只是指向内存的指针,因此 memcpy() 和该系列中的其他函数将按预期工作。No, they are perfectly fine.
new
andmalloc()
are just two different ways in you can aquire memory on the heap (actually they are quite the same, becausenew
usesmalloc()
under the hood in most implementations). As soon as you have a validchar*
variable in your hand (allocated bynew
,malloc()
or on the stack) it is just a pointer to memory, hencememcpy()
and other functions from this family will work as expected.对于 char 数组数据,即使与 new 结合使用也应该可以正常工作。
但在 C++ 中为什么不使用 std::copy 或 std::copy_backward 并完全消除这个问题?
For char array data it should work fine even in conjunction with new.
But in C++ why not use std::copy or std::copy_backward and eliminate the question completely?
这实际上取决于您的平台以及编译器对 new 和 memmove 的实现。大多数处理器架构在字边界对齐时可以更好地打乱数据,但有些处理器架构在其他情况下性能更好。例如,PowerPC 7447 在内存对齐 16 字节边界 时工作速度最快。这是其 Altivec SIMD 指令集的向量寄存器的大小,因此可以在分配于 16 字节边界的数组上更快地实现 memcpy 或类似函数。有关示例,请参阅此问题。
为什么这对新事物有影响?因为 new 运算符可以在它返回的指针之前的几个字节中存储有关已分配内存块的一些元数据,所以它给您的实际指针是在分配的实际开始之后的一个或两个字。在我遇到这种行为的 CPU、操作系统和编译器(PowerPC 7447a、VxWorks 5.5、GCC 2.95)上,新运算符保证为您提供 8 字节对齐但不是 16 字节对齐的块。当然,这是非常具体的实现。我不相信 C++ 标准中有任何指定对齐的内容,因为这将是特定于体系结构的优化。
所有这一切的要点是,如果您在某个平台上并且关心对齐等低级优化问题,则可能会产生轻微的性能差异。对于大多数应用程序,您可能不需要担心这一点。
That actually depends on your platform, and your compiler's implementation of
new
andmemmove
. Most processor architectures shuffle data around better when they are aligned on word boundaries, but some have additional cases where they perform better. The PowerPC 7447, for example, works fastest with memory aligned on 16 byte boundaries. That is the size of the vector registers for its Altivec SIMD instruction set, so memcpy or a similar function can be implemented to be much faster on arrays that are allocated on 16 byte boundaries. See this question for an example.Why does this make a difference for new? Because the new operator can store some meta-data about the allocated block of memory in the couple of bytes before the pointer that it returns, so the actual pointer it gives you is a word or two past the actual beginning of the allocation. On the CPU, OS, and compiler where I encountered this behavior (PowerPC 7447a, VxWorks 5.5, GCC 2.95) the new operator was guaranteed to give you blocks that were 8 byte aligned but were not 16 byte aligned. This is, of course, very implementation specific. I don't believe there is anything in the C++ standard that specifies alignment since that is going to be an architecture specific optimization.
The point of all this is that it might make a slight performance difference if you are on a certain platform and care about low level optimization issues like alignment. You probably don't need to worry about this for most applications.
我仍然会使用带有 std::copy 的向量,但这并不意味着 new/memcpy/memmove 不好。如果您坚持在缓冲区内移动部件,memmove 实际上是首选。
I would still use vector with std::copy, but that doesn't mean new/memcpy/memmove is bad. memmove is actually preferred if you insist on moving parts within the buffer.