Reputation: 697
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?
Upvotes: 8
Views: 15614
Reputation: 1
I don't have reputation score >= 50, so I can't post the comment, even as the original author of the commented post -> which is simply stupid from my point of view...
So, here's my answer for the comment posted by user207421:
SIMD instructions are implemented in every CPU used in PCs in the last 20 years (at least), so unless You're using some very old CPU, your claim regarding "recent enough" CPUs is basically invalid.
See point 2 in my post above: "the fastest architecture-dependant methods" means that f.e. on an 8-bit AVR, the "movw" instruction can be (and it is) used to implement fast memcpy-like functions, because it works similarly to SIMD on x86: it can copy 2 8-bit CPU words in a single cycle.
Regards.
Upvotes: 0
Reputation: 15134
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.
Upvotes: 0
Reputation: 1
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:
I suggest to actually read the code before posting incorrect answers.
Upvotes: -1
Reputation: 7929
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.
Upvotes: 2
Reputation: 45057
A few problems with your code as it stands:
int
. Since int
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 of memcpy
.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). Using memcpy
on integers may or may not do what you expect. It's best to use byte arrays when learning how memcpy
and friends work.memcpy
uses pB+1
as the target. This doesn't advance the pointer one byte, it advances it by sizeof(*pB)
bytes. In this case, that leaves it pointing to an invalid address (past the end of the variable). This call to memcpy
will corrupt random memory, which can crash your program or cause unpredictable results.Upvotes: 9
Reputation: 16906
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].
Upvotes: 0
Reputation: 3247
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.
Upvotes: 1