Thread: memcpy - & or not?

  1. #1
    Registered User
    Join Date
    Nov 2016
    Posts
    84

    memcpy - & or not?

    Hi,

    I want to use memcpy to copy parameters. I am not sure whether my usage of & is correct or not? Could someone help me please?

    Code:
        memcpy(m_msgParms.m_mqprReplyQueue, msgDescriptor.ReplyToQ, sizeof(m_msgParms.m_mqprReplyQueue)); //MQCHAR48
        //m_mqprReplyQueue[48];
    
        memcpy(m_msgParms.m_mqprMessageId, msgDescriptor.MsgId, sizeof(m_msgParms.m_mqprMessageId)); //MQBYTE24
         //char m_mqprMessageId[24];
    
        memcpy(m_msgParms.m_mqprFormat, msgDescriptor.Format, sizeof(m_msgParms.m_mqprFormat)); //MQCHAR8
         //char m_mqprFormat[4];
    
        memcpy(m_msgParms.m_mqprPersistency, &msgDescriptor.Persistence, sizeof(m_msgParms.m_mqprPersistency)); //MQLONG
         //char m_mqprPersistency[4];
    My struct-members (m_msgParms) are char arrays. The data types after // are the data types from the source (MsgDescriptor)
    Last edited by Joe1903; 11-03-2019 at 08:01 AM.

  2. #2
    Registered User
    Join Date
    Aug 2019
    Location
    inside a singularity
    Posts
    308
    You should be using a & (reference) operator when you want, maybe, an alias or to prevent copying of the contents of one location in memory into another. memcpy's second argument takes a const void* source. Persistence is a pointer to an array of char, so what you want is probably just msgDescriptor.Persistence and not the reference to Persistence as your source in the second argument. Passing &Persistence will pass the memory address of Persistence instead of passing the pointer to the contents of the array which is held inside the memory location of Persistence, which is not what you want.

  3. #3
    Registered User
    Join Date
    Nov 2016
    Posts
    84
    Ok thank you very much.If my second Argument is pointer, I have to use &,correct?
    const char * data = buffer.getBuffer();

    memcpy(m_mqprMessageP, &data, sizeof(m_mqprMessageP));

    I want to set a Pointe to the buffer.
    Last edited by Joe1903; 11-03-2019 at 08:48 AM.

  4. #4
    Registered User
    Join Date
    Aug 2019
    Location
    inside a singularity
    Posts
    308
    Ignore my message in #2. I realised I'm wrong in my explanation as I confused myself a bit... Sorry about that.

    Let's say you have an array A.

    Code:
    int A [] = { 1 , 2 , 3 , 4 , 5 , 6 , 7 };
    cout << A; // Some memory location 0xCCCCCCCC
    cout << *A; // 1
    cout << &A; // Will also give you 0xCCCCCCCC contrary to what I said in #2 (confused myself a teeny bit...) but remember this: A is a pointer to the first element so you can do something like:
    cout << *(A + 1); // which yields you 2, but you cannot do this:
    cout << &A + 1; // as &A is a pointer to your entire array, by pointer arithmetic, you end up at a location (7 * sizeof(int)) ahead of where A points to which is out of the bound of your array
    So, in your example, you can just pass 'data' as it's a pointer itself. Since, &data will point to the entire array of char, you could pass that too as source, as both hold the same memory location in case of arrays.

    [EDIT]
    Also, it might be worth noting that an array knows its size in general but a pointer doesn't
    [/EDIT]
    Last edited by Zeus_; 11-03-2019 at 09:32 AM.

  5. #5
    Registered User
    Join Date
    Nov 2016
    Posts
    84
    Quote Originally Posted by Zeus_ View Post
    Ignore my message in #2. I realised I'm wrong in my explanation as I confused myself a bit... Sorry about that.

    Let's say you have an array A.

    Code:
    int A [] = { 1 , 2 , 3 , 4 , 5 , 6 , 7 };
    cout << A; // Some memory location 0xCCCCCCCC
    cout << *A; // 1
    cout << &A; // Will also give you 0xCCCCCCCC contrary to what I said in #2 (confused myself a teeny bit...) but remember this: A is a pointer to the first element so you can do something like:
    cout << *(A + 1); // which yields you 2, but you cannot do this:
    cout << &A + 1; // as &A is a pointer to your entire array, by pointer arithmetic, you end up at a location (7 * sizeof(int)) ahead of where A points to which is out of the bound of your array
    So, in your example, you can just pass 'data' as it's a pointer itself. Since, &data will point to the entire array of char, you could pass that too as source, as both hold the same memory location in case of arrays.

    [EDIT]
    Also, it might be worth noting that an array knows its size in general but a pointer doesn't
    [/EDIT]
    Ok I am confused but I try to explain what I understand:

    As data is already a pointer it can be passed as data or &data,the result would be the same.And all other parameters which I extract from MsgDescriptor should be without & (memcpy(msgParms.m_paramater, msgDescriptor.parameter, sizeof(msgParms.m_parameter));

    Is that correct?

  6. #6
    Registered User
    Join Date
    Aug 2019
    Location
    inside a singularity
    Posts
    308
    Your ReplyToQ, MsgID and Format are all char arrays, and you haven't passed them as their & equivalent so it only makes sense to do the same for Persistence. As everything is already a pointer, and memcpy expects a void* and a const void*, pass them without the &.

    > Is that correct?

    Yep

  7. #7
    Registered User
    Join Date
    Nov 2016
    Posts
    84
    Quote Originally Posted by Zeus_ View Post
    Your ReplyToQ, MsgID and Format are all char arrays, and you haven't passed them as their & equivalent so it only makes sense to do the same for Persistence. As everything is already a pointer, and memcpy expects a void* and a const void*, pass them without the &.

    > Is that correct?

    Yep
    This is my complete memcpy-part. In that case, it should work now (all of my members are char [] and HyqcmqprParms is my struct):

    Code:
    const BASBuffer & buffer = msg->buffer(); 
        const char * data = buffer.getBuffer(); 
        MQLONG dataLength = buffer.tell();    
    
    
        m_msgParms = new HyqcmqprParms(); //create new object on heap
        memset(m_msgParms, 0, sizeof (*m_msgParms)); // set all members to 0
    
    
        memcpy(m_msgParms.m_eyeCatcher, validEyeCatcher, sizeof(m_msgParms.m_eyeCatcher)); //const char
    
        memcpy(m_msgParms.m_version, version_1_0, sizeof(m_msgParms.m_version)); //const char
    
        memcpy(m_msgParms.m_mqprQueueMgr, msgDescriptor.ReplyToQMgr, sizeof(m_msgParms.m_mqprQueueMgr));
    
        memcpy(m_msgParms.m_mqprQueue, m_queueinfo.m_queueName, sizeof(m_msgParms.m_mqprQueue)); //const char
    
        memcpy(m_msgParms.m_mqprReplyQueue, msgDescriptor.ReplyToQ, sizeof(m_msgParms.m_mqprReplyQueue));
     
        memcpy(m_msgParms.m_mqprMessageP, &data, sizeof(m_msgParms.m_mqprMessageP));
        
        memcpy(m_msgParms.m_mqprMessageL, dataLength, sizeof(m_msgParms.m_mqprMessageL));
    
        memcpy(m_msgParms.m_mqprMessageId, msgDescriptor.MsgId, sizeof(m_msgParms.m_mqprMessageId));
    
        memcpy(m_msgParms.m_mqprCorrelId, msgDescriptor.CorrelId, sizeof(m_msgParms.m_mqprCorrelId));
    
        memcpy(m_msgParms.m_mqprCommitScope, putMsgOptions.Options, sizeof(m_msgParms.m_mqprCommitScope));
    
        memcpy(m_msgParms.m_mqprFormat, msgDescriptor.Format, sizeof(m_msgParms.m_mqprFormat));
    
        memcpy(m_msgParms.m_mqprPersistency, msgDescriptor.Persistence, sizeof(m_msgParms.m_mqprPersistency));
    
        memcpy(m_msgParms.m_mqprPriority, msgDescriptor.Priority, sizeof(m_msgParms.m_mqprPriority));
    
        memcpy(m_msgParms.m_mqprExpiry, msgDescriptor.Expiry, sizeof(m_msgParms.m_mqprExpiry));
    
        memcpy(m_msgParms.m_mqprTargetEntity, ' ', sizeof(m_msgParms.m_mqprTargetEntity));
    
        memcpy(m_msgParms.m_mqprSwid, ' ', sizeof(m_msgParms.m_mqprSwid));
    
        memcpy(m_msgParms.m_reserved1, ' ', sizeof(m_msgParms.m_reserved1));
    Last edited by Joe1903; 11-03-2019 at 10:44 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. memcpy
    By ueg1990 in forum C Programming
    Replies: 3
    Last Post: 07-05-2012, 04:39 AM
  2. Help memcpy!
    By Kozay Novel in forum C Programming
    Replies: 9
    Last Post: 07-04-2012, 08:46 PM
  3. memcpy
    By m37h0d in forum C++ Programming
    Replies: 28
    Last Post: 04-12-2008, 09:10 PM
  4. memcpy()
    By Moni in forum C++ Programming
    Replies: 3
    Last Post: 09-05-2006, 05:31 AM
  5. memcpy
    By mbooka in forum C Programming
    Replies: 10
    Last Post: 02-28-2006, 02:25 AM

Tags for this Thread