Thread: memcpy assistance please

  1. #1
    Registered User cyberCLoWn's Avatar
    Join Date
    Dec 2003
    Location
    South Africa
    Posts
    124

    memcpy assistance please

    Basically what I am trying to do is modify the contents of the place where the structures data pointer points to. I have to add 5 arb characters onto the packet's data.

    When I run the program below, it crashes when performing the memcpy and I have no idea why. Please could somone assist me.

    Thanks!

    Code:
    struct packet {
        int length; // length of the data packet
        unsigned char *data; // pointer to data area
    };
    
    void addHeader(packet);
    void stripHeader(packet);
    
    int main() {
        unsigned char *d = (unsigned char*) "45100035A0ED400";
        packet p = {15, d};
        cout << "Original data: " << d << endl;
        addHeader(p);
        cout << "headerAdd: " << p.data << endl;
        //stripHeader(p);
        //cout << "stripHeader: " << p.data << endl;
        
        cin.get(); // pauses program;
        return 0;
    }
        
    void addHeader(packet x) {
        unsigned char temp[20] = {'A','F','A','F','1'};
        int count = 0;
        
        for(int i = 5; i < (sizeof(temp)/sizeof(char)); i++) { // appends x.data onto temp
            temp[i] = x.data[count];
            count++;
        }
        memcpy(x.data, temp, 20);   
    }

  2. #2
    Registered User Micko's Avatar
    Join Date
    Nov 2003
    Posts
    715
    Prototype of memcpy is:
    Code:
    void *memcpy(
       void *dest,
       const void *src,
       size_t count 
    );
    As you can see it needs addresses of variables!
    Make sure you have enough room to place 20 characters!
    Also your function addHeader receive copy of variable p, maybe you shpould use pointers!
    According to C/C++ standard sizeof(char) is always 1 so you don't need to write (sizeof(temp)/sizeof(char) since it is 20.
    Last edited by Micko; 08-06-2006 at 10:31 AM.
    Gotta love the "please fix this for me, but I'm not going to tell you which functions we're allowed to use" posts.
    It's like teaching people to walk by first breaking their legs - muppet teachers! - Salem

  3. #3
    Registered User cyberCLoWn's Avatar
    Join Date
    Dec 2003
    Location
    South Africa
    Posts
    124
    Code:
        memcpy(&x.data, &temp, 20);
    Right I see that. It does not crash now, but however it outputs the original data that was first outputted.

    As for the sizeof, yeah I guess you're right.

    I have to stick to the way I have defined the struct according to the problem's specs.
    Last edited by cyberCLoWn; 08-06-2006 at 10:41 AM.

  4. #4
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Quote Originally Posted by cyberCLoWn
    Basically what I am trying to do is modify the contents of the place where the structures data pointer points to. I have to add 5 arb characters onto the packet's data.

    When I run the program below, it crashes when performing the memcpy and I have no idea why. Please could somone assist me.
    Use writable arrays.
    Last edited by Dave_Sinkula; 08-06-2006 at 10:30 AM. Reason: Pokey fingers. :(
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  5. #5
    Registered User cyberCLoWn's Avatar
    Join Date
    Dec 2003
    Location
    South Africa
    Posts
    124
    Code:
    void addHeader(packet x) {
        unsigned char temp[20] = {'A','F','A','F','1'};
        int count = 0;
        
        for(int i = 5; i < 20; i++) {
            temp[i] = x.data[count];
            count++;
        }
        cout << temp;
        memcpy(&x.data, temp, 20);   
    }
    When using the above code, it outputs the temp array perfectly and memcpy doesn't crash the program. However later on in the main function when it outputs p.data nothing has been changed.

  6. #6
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    String literals are not writeable.

    Aren't you going about this a little backwards anyways? Wouldn't you have a structure that contains the header and the packet? I'm thinking something along this line:
    Code:
    struct packet
    {
       int length;
       unsigned char *data;
    };
    
    struct T
    {
       unsigned char header[5];
       struct packet packet;
    };
    
    void addPacket(struct packet *packet)
    {
       struct packet stuff = { 15, "45100035A0ED400" };
       *packet = stuff;
    }
    
    int main()
    {
       struct T t = { { 'A','F','A','F','1' } };
       addPacket(&t.packet);
       /* ... */
       return 0;
    }
    (Poor and unfinished and all that -- merely a poke in a different direction.)

    [edit=yet another]More work in progress:
    Code:
    struct packet
    {
       int length;
       unsigned char *data;
    };
    
    struct T
    {
       unsigned char header[5];
       struct packet packet;
    };
    
    void addHeader(struct T *t)
    {
       unsigned char header[] = { 'A','F','A','F','1' };
       memcpy(t->header, header, sizeof t->header);
    }
    
    void addPacket(struct packet *packet)
    {
       struct packet stuff = { 15, "45100035A0ED400" };
       *packet = stuff;
    }
    
    int main()
    {
       struct T t;
       addHeader(&t);
       addPacket(&t.packet);
       /* ... */
       return 0;
    }
    Last edited by Dave_Sinkula; 08-06-2006 at 11:08 AM. Reason: Twiddled code some more.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  7. #7
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Try something like this
    Code:
    #include <iostream>
    using namespace std;
    
    struct packet {
        int length;          // length of the data packet
        unsigned char *data; // pointer to data area
    };
    
    void addHeader(packet& );
    
    const int hdrlen = 5;
    
    int main() {
        char * d = "45100035A0ED400";                       // this is a string literal that cannot be modified    
        packet p;
        
        p.length = strlen(d);                               // don't like magic numbers
        p.data = new unsigned char[p.length + hdrlen + 1];  // added 1 to make it printable
        strcpy( reinterpret_cast<char*>(p.data), d );       // cast needed char and unsigned char are not related 
         
        cout << "Original data: " << d << endl;
        addHeader(p);
        cout << "headerAdd: " << p.data << endl;
        
        delete [] p.data;
        
        return 0;
    }
        
    void addHeader(packet & x) {                           // needs to be a reference x is supposed to be modified
        unsigned char temp[21] = {'A','F','A','F','1'};
        int count = 0;
            
        for(int i = 0; i < x.length + 1; i++) {
            temp[hdrlen+i] = x.data[count];
            count++;
        }
        
        memcpy( x.data, temp, x.length + hdrlen + 1);
    }
    Kurt

    EDIT: little late ( did I really need half an hour to do this ? )
    Last edited by ZuK; 08-06-2006 at 11:35 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 14
    Last Post: 06-28-2006, 01:58 AM
  2. Memcpy(); Errors...
    By Shamino in forum C++ Programming
    Replies: 4
    Last Post: 03-24-2006, 11:35 AM
  3. memcpy with 128 bit registers
    By grady in forum Linux Programming
    Replies: 2
    Last Post: 01-19-2004, 06:25 AM
  4. Trying to copy buffers using memcpy in C under UNIX
    By Meeper in forum C Programming
    Replies: 3
    Last Post: 07-26-2003, 08:51 AM
  5. memcpy
    By doubleanti in forum C++ Programming
    Replies: 10
    Last Post: 02-28-2002, 04:44 PM