memcpy a int to a char buffer ?

Discussion in 'C++' started by Juergen Wohnich, Jan 23, 2006.

  1. Hello,
    i want to do store int variablen into a char Buffer.
    Like this:

    char Buffer[1024];
    int b = 1447;
    int *pb; // pb deklariert als pointer auf int
    pb = &b; // & ist Adress operator, liefert Adresse von b
    memcpy( Buffer, pb, 4 );

    This seem to work but now i want to copy the int Variable to another
    position in the buffer. How do i this ?
    This causes a error:

    char Buffer[1024];
    int b = 1447;
    int *pb; // pb deklariert als pointer auf int
    pb = &b; // & ist Adress operator, liefert Adresse von b
    memcpy( Buffer[100], pb, 4 ); // cause: error C2664: 'memcpy' : cannot
    convert parameter 1 from 'char' to 'void *'

    How can i do this ?
     
    Juergen Wohnich, Jan 23, 2006
    #1
    1. Advertising

  2. Juergen Wohnich

    Jim Langston Guest

    "Juergen Wohnich" <> wrote in message
    news:dr1liu$hii$...
    > Hello,
    > i want to do store int variablen into a char Buffer.
    > Like this:
    >
    > char Buffer[1024];
    > int b = 1447;
    > int *pb; // pb deklariert als pointer auf int
    > pb = &b; // & ist Adress operator, liefert Adresse von b
    > memcpy( Buffer, pb, 4 );
    >
    > This seem to work but now i want to copy the int Variable to another
    > position in the buffer. How do i this ?
    > This causes a error:
    >
    > char Buffer[1024];
    > int b = 1447;
    > int *pb; // pb deklariert als pointer auf int
    > pb = &b; // & ist Adress operator, liefert Adresse von b
    > memcpy( Buffer[100], pb, 4 ); // cause: error C2664: 'memcpy' : cannot
    > convert parameter 1 from 'char' to 'void *'
    >
    > How can i do this ?


    To answer the error you are getting, Buffer[100] is the char at position
    101. You just want the address of this or
    &Buffer[100].
     
    Jim Langston, Jan 23, 2006
    #2
    1. Advertising

  3. Juergen Wohnich

    Henryk Guest

    Re: memcpy a int to a char buffer ?

    you can do some casting to get the same result

    *(reinterpret_cast<int*>(&Buffer[the_position_you_want_to_start])) = n;

    Some comments:
    - get char pointer with &Buffer[the_position_you_want]
    - cast this point to int pointer with reinterpret_cast<int*>(...)
    - set the value at that pointers address with *(...) = b

    --

    Henryk
     
    Henryk, Jan 23, 2006
    #3
  4. Juergen Wohnich

    Andre Kostur Guest

    Re: memcpy a int to a char buffer ?

    "Henryk" <> wrote in news:1138041999.340362.153120
    @g49g2000cwa.googlegroups.com:

    > you can do some casting to get the same result
    >
    > *(reinterpret_cast<int*>(&Buffer[the_position_you_want_to_start])) = n;
    >
    > Some comments:
    > - get char pointer with &Buffer[the_position_you_want]
    > - cast this point to int pointer with reinterpret_cast<int*>(...)
    > - set the value at that pointers address with *(...) = b


    Oh no you can't.... (not according to the Standard anyway). Try it on the
    Sparc platform for example. If the_position_you_want doesn't result in a
    correctly aligned memory access for deferencing that pointer... your
    program will crash (one possible result for the Undefined Behaviour that
    was invoked).
     
    Andre Kostur, Jan 23, 2006
    #4
  5. Juergen Wohnich

    Henryk Guest

    Re: memcpy a int to a char buffer ?

    Ok, that is new to me.

    We have Sparc Leons inhouse. But it is too long ago that I worked with
    to remember...

    Just for my interest:

    Could you give some more explanation why it would crash? Must an
    integer value 2- or 4-byte aligned in memory? What about derefencing
    the pointer back to char? Are there any alignment constraints then?
    What about 1-byte packed structures?
     
    Henryk, Jan 24, 2006
    #5
  6. Juergen Wohnich

    Andre Kostur Guest

    Re: memcpy a int to a char buffer ?

    "Henryk" <> wrote in news:1138106524.148895.293440
    @g49g2000cwa.googlegroups.com:

    > Ok, that is new to me.
    >
    > We have Sparc Leons inhouse. But it is too long ago that I worked with
    > to remember...
    >
    > Just for my interest:
    >
    > Could you give some more explanation why it would crash? Must an
    > integer value 2- or 4-byte aligned in memory? What about derefencing
    > the pointer back to char? Are there any alignment constraints then?
    > What about 1-byte packed structures?


    As I recall, due to the instruction set on the processor, it can't
    load/store an int-sized chunk of memory into a register from an unaligned
    memory address.

    So, with the example:

    char buffer[1024];

    *(reinterpret_cast<int *>(&buffer[1])) = 2;

    The compiler may emit the machine code to load 2 into a register, then
    attempts to store the register into the memory address &buffer[1]. The
    hardware doesn't allow it, so the CPU generates a trap. This ends up
    manifesting itself as a bus error in your program, and your program
    crashes.

    Accessing an int inside a 1-byte packed structure isn't an issue since
    the compiler can examine your int access and realize that since it is
    accessing the int from an unaligned address it will emit the machine code
    to do the extra memory accesses (in order to comply with the aligned
    memory access rules) to compose the int. So if you had (assuming
    whatever compiler magic to make it 1-byte aligned):

    struct st
    {
    char ch;
    int anInt;
    };

    st stVar;
    char * overlay = reinterpret_cast<st *>(&stVar);

    In the example above it reads the 4 bytes starting at &overlay[0] into a
    register, left shifts it 8 to throw away the 1st byte, then load the byte
    at &overlay[4] and bitwise-or it with the working register to finally get
    the complete int. Note that &stVar is by definition correctly aligned
    for an object of type st.

    To bring this discussion back to the Standard realm (from Sparc-
    specific), the original code has undefined behaviour because you're
    casting a pointer between unrelated types (and not void*).

    What does work:

    char buffer[1024];
    int someInt(2);

    memcpy(&buffer[1], &someInt, sizeof(someInt));

    memcpy has to be able to deal with unaligned memory copies, so this would
    work. (Exactly how it works is the problem of the compiler implementor,
    as well as any sort of optimizations)
     
    Andre Kostur, Jan 24, 2006
    #6
  7. Juergen Wohnich

    Henryk Guest

    Re: memcpy a int to a char buffer ?

    Ok, thank you. Got your point.

    About the undefined behavior:

    I thought the purpose of reinterpret_cast is to tell the compiler "shut
    up I know what I do", which is true sometimes...

    I do this cast pretty often. For instance to extract data from a byte
    stream. Suppose the byte stream contains a float value somewhere
    (possibly bytes had to be swapped before fron sender/receiver because
    of endian mismatch). This cast is the most efficient way to extract the
    data.

    The overhead of memcpy for only a few bytes (8 for float) is just too
    much.

    It worked so far but good to know the pifalls at some machines as you
    pointed it out.

    Greets

    --

    Henryk
     
    Henryk, Jan 24, 2006
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. hs
    Replies:
    2
    Views:
    8,424
    John Harrison
    Jul 30, 2004
  2. Schnoffos
    Replies:
    2
    Views:
    1,219
    Martien Verbruggen
    Jun 27, 2003
  3. trey

    newbie: char* int and char *int

    trey, Sep 10, 2003, in forum: C Programming
    Replies:
    7
    Views:
    405
    Irrwahn Grausewitz
    Sep 10, 2003
  4. Hal Styli
    Replies:
    14
    Views:
    1,646
    Old Wolf
    Jan 20, 2004
  5. gert
    Replies:
    20
    Views:
    1,167
Loading...

Share This Page