问题
int a = 10;
int* pA = &a;
long long b = 200;
long long* pB = &b;
memcpy (pB,pA,4);
memcpy (pB+1,pA,4);
cout<<"I'm a memcpy!: "<<*(pB)<<endl;
I'm doing some tests with memcpy to teach myself how memory works. What I am trying to do is make b = to "1010". I can copy the value from a to b, but then I try to offset the memory by 1 byte and write another 10 but it doesn't work it only outputs "10".
What would I need to do to get a value of 1010?
回答1:
A few problems with your code as it stands:
- You copy 4 bytes, but the destination is type
int
. Sinceint
is not guaranteed to be any particular size, you need to make sure that it is at least 4 bytes long before you do that sort ofmemcpy
. memcpy
works on the byte level, but integers are a series of bytes. Depending on your target architecture, the bytes within an integer may be arranged differently (big-endian, little-endian, etc). Usingmemcpy
on integers may or may not do what you expect. It's best to use byte arrays when learning howmemcpy
and friends work.- Your second
memcpy
usespB+1
as the target. This doesn't advance the pointer one byte, it advances it bysizeof(*pB)
bytes. In this case, that leaves it pointing to an invalid address (past the end of the variable). This call tomemcpy
will corrupt random memory, which can crash your program or cause unpredictable results.
回答2:
I don't think memcpy()
is designed for what you want. In general, you would use memcpy()
to copy one or more whole objects (where an object might be an int, a char, a long long, etc.)
int a[4] = { 1, 2, 3, 4 };
int b[3];
int c[5] = { 0 };
::memcpy(b, a, 3 * sizeof(int)); // b is { 1, 2, 3 }
::memcpy(c+2, b, 3 * sizeof(int)); // c is { 0, 0, 1, 2, 3 }
c+2 is not "c + 2 bytes". It is "c + 2 ints" (8 bytes on a Win32/x86 system).
You can access the individual bytes by casting to a char or unsigned char pointer, but I don't recommend that unless you really understand what you're doing as there are many pitfalls.
unsigned x = 0;
unsigned char *px = reinterpret_cast<unsigned char *>(&x);
px[0] = 0xFF;
px[2] = 0xAA;
One of the dangers here is that you are assuming knowledge about how the computer stores an integer. On an x86 system, x will be 0x00AA00FF but on a Sun Sparc system it will be 0xFF00AA00.
if you need to set parts of an integer it is often better to use "or" and "shift".
x = (0xFF<<24) | (0xAA<<8);
will give you 0xFF00AA00 on any architecture. 0xFF<<24 shifts the value 0xFF by 24 bits to the left, making 0xFF000000. 0xAA<<8 shifts the value 0xAA by 8 bits to the left, making 0x0000AA00.
We "or" them together, giving 0xFF00AA00.
回答3:
Look into pointer arithmetic: http://www.cs.umd.edu/class/sum2003/cmsc311/Notes/BitOp/pointer.html . Adding a value to a pointer actually incrememnts by that many units of whatever size you're dealing with.
回答4:
pB is of type long long*, so adding 1 to it will give the address to the next set of eight bytes following variable b. You have pB[0] being the variable b, but pB[1] (equivalent to pB+1) point to undefined memory. Writing to it will likely cause a crash.
Replace
long long b;
with
long long b[2];
(use whatever initial values you like)
Your cout will need to be fed both b[0] and b[1].
回答5:
If you want to copy "10" to the bytes afterward and get "1010", you want to copy the string. This is really the job of strcat()
rather than memcpy()
, but here is a way you could do it with memcpy()
:
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
constexpr char src[] = "10";
constexpr size_t n = sizeof(src) - 1; // Don’t count the terminator.
char dest[2*n+1] = {'\0'}; // Will hold: {'1','0','1','0','\0'}
static_assert( sizeof(dest) > 2*n, "" ); // Always check array bounds in C++!
memcpy( dest, src, n );
memcpy( dest + n, src, n );
puts(dest);
return EXIT_SUCCESS;
}
In particular, observe that the destination is an array of bytes long enough to hold both copies.
回答6:
memcpy works on the byte level, but integers are a series of bytes.
WRONG explanation.
The above answer would be more or less true for a strcpy()
, but it's entirely wrong in case of memcpy()
, because all the mem_xxx()
functions are using SIMD instructions to speed-up the operations.
If the memcpy()
function would be based on byte-by-byte copying, it would be deadly slow...
Basically, all of the mem_xxx
functions are implemented like this:
- If the source and/or destination pointers are unaligned, then those functions are aligning the pointers by first processing the unaligned/odd memory chunks.
- Next, the fastest architecture-dependant methods are used to process the aligned memory area.
- Finally, the remaining unaligned/odd bytes are processed.
I suggest to actually read the code before posting incorrect answers.
来源:https://stackoverflow.com/questions/11025029/understanding-memcpy