25

I have the following pointer:

jfloat *verticesLocal;

And I want make a new copy to:

jfloat *vertices;

I want to copy the values from verticesLocal to vertices.

How can I do that? I've just tried the following command, but it doesn't work:

memcpy(vertices, verticesLocal, numVerticesLocal * sizeof(jfloat));

I can't see the error because I'm working with Android native code. Sorry.

A-Sharabiani
  • 17,750
  • 17
  • 113
  • 128
VansFannel
  • 45,055
  • 107
  • 359
  • 626
  • Did you allocate space for vertices? You should have done a calloc or malloc beforehand somewhere. – SRM Dec 10 '10 at 16:50
  • 3
    What do you mean by copy a pointer? Just copy the value (address) or make a copy of the contents of whatever is pointed to? – The Archetypal Paul Dec 10 '10 at 16:51
  • I want to copy the values from `verticesLocal` to `vertices`. – VansFannel Dec 10 '10 at 16:54
  • The values from that `verticesLocal` points to, to the locations where `vertices` points to? If so, and they both point to sufficiently sized and aligned memory then your `memcpy` call is correct. – CB Bailey Dec 10 '10 at 17:09
  • It works perfectly when I do a malloc before memcpy, as @aix and @lijie have suggested. – VansFannel Dec 10 '10 at 17:18
  • This is not copying pointers. This is copying VALUES. You copy a value that is pointed at in exactly the same way as one that is not. You copy POINTERS by assigning the src to the destination just like you would with any other integral. – Edward Strange Dec 10 '10 at 18:54
  • Sorry, but English is not my mother tongue. I make mistakes. – VansFannel Dec 10 '10 at 18:58

4 Answers4

57

The idea of "copying a pointer", when taken literally, is nothing more than a simple assignment.

int x = 5;
int* p1 = &x;
int* p2 = p1; // there, we copied the pointer.

In this case, both p1 and p2 point to the same data - the int variable x. However, because this is so trivial, I'm inclined to think that what you really are asking about is how to copy the data that the pointer points to.

In this case, it depends on the data type. If the pointer points to a simple buffer of PODs, this involves allocating a separate buffer, and then using something like memcpy (or preferably std::copy) to copy the data. For example:

int* p1 = new int[100];
// ... fill p1 with values
int* p2 = new int[100]; // create a new buffer
std::copy(p1, p1 + 100, p2); // copy the data into p2

Or, you can use memcpy to copy the buffer byte-by-byte, since the buffer contains PODs.

memcpy(p2, p1, 100 * sizeof(int));

However, if the pointed-to data is not a simple buffer, but rather a C++ object, you can't use memcpy. You need to perform a deep copy of the object, (usually using the object's copy constructor) to get a clone of the object. How this is done, or whether it's even possible, depends on the object. (Some objects are noncopyable.)

I have no clue what a jfloat is, but if the object is, for example, an std::string, you would just do something like:

std::string* s1; // assume this points to a valid string
std::string* s2 = new std::string();
*s2 = *s1; // copies s1 using s2's assignment operator

In this contrived example it would be preferable to avoid heap-allocation altogether, and just use stack variables. But it demonstrates the idea of copying a heap-allocated object.

Community
  • 1
  • 1
Charles Salvia
  • 52,325
  • 13
  • 128
  • 140
  • You mentioned that some objects are noncopyable, when is this the case? – Dennis Aug 01 '13 at 07:18
  • 1
    @Dennis, if the object has a `private` or `delete`d copy constructor, or contains any internal data members with `private` or `delete`d copy constructors, the object cannot be copied via the copy constructor. An example of such an object is `std::fstream`; you cannot call `fstream::fstream(const fstream&)` - the compiler will generate an error. In C++11 it can be moved, however. – Charles Salvia Aug 01 '13 at 13:04
18

malloc first, then do your memcpy.

NPE
  • 486,780
  • 108
  • 951
  • 1,012
4

If you are copying the pointer, it is a simple assignment:

jfloat* verticesLocal; // assuming is is allocated already
jfloat* newVertices = verticesLocal;

IF you mean you want to copy the data the point points to, you have to allocate the memory for the new block of memory first:

// assume jfloat* verticesLocal is pointing to a valid memory block of size i

jfloat* newVertices = new jfloat[i];
memcpy(newVertices, verticesLocal, i * sizeof(jfloat));
Zac Howland
  • 15,777
  • 1
  • 26
  • 42
  • See my comment to Nate, but that what you illustrate here is precisely the difference between a shallow copy and a deep copy. Depending on your particular solution either may be applicable. – SRM Dec 10 '10 at 17:02
  • @SRM: Which is why I provided both examples. – Zac Howland Dec 10 '10 at 17:14
0

this is how you copy an array buffer :

    unsigned char *pBufferSrc = new unsigned char[10];  
    unsigned char *pBufCpd = new unsigned char[10];

    for (int i = 0; i < 10; i++)
         pBufferSrc[i] = i;        // pBufferSrc = [0,1,2,3,4,5,6,7,8,9]


     memcpy(pBufCpd, pBufferSrc, 10);   // data from pBufferSrc is copied to pBufCpd (0,1,2,..9)

     delete []pBufferSrc;       // if even pBufferSrc buffer gets deleted, pBufCpd still has the data
Zrn-dev
  • 99
  • 5