views:

383

answers:

5

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?

+4  A: 

Using memcpy()/memmove() should work fine on that kind of data. In general, you can use them safely on any POD type.

Carl Norum
POD-ness is the key.
Ben Voigt
+3  A: 

No, they are perfectly fine. new and malloc() are just two different ways in you can aquire memory on the heap (actually they are quite the same, because new uses malloc() under the hood in most implementations). As soon as you have a valid char* variable in your hand (allocated by new, malloc() or on the stack) it is just a pointer to memory, hence memcpy() and other functions from this family will work as expected.

pajton
It should be noted that you have to have a `char *` variable that's valid. `char *c = NULL;` or `char *c = 0xfacefeed;` will probably not play nicely with `memcpy()` or `memmove()`.
Chris Lutz
Edited to clarify this case. Thanks!
pajton
+2  A: 

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?

Mark B
A: 

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.

stefaanv
+1  A: 

That actually depends on your platform, and your compiler's implementation of new and memmove. 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.

A. Levy
"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" - just like malloc(), then.
anon
Yes. Just like malloc. Some platforms provide an alternative memory allocation function that allows you to specify the alignment boundary of the memory. If you really care about alignment, you should look for one of these routines.
A. Levy