0

I tried to memcpy measure_msg (struct test) to a buffer. However, the code below doesn't seems to copy the data. The value return

**** ptr:0xb781c238
**** ptr:0xb781c23c
**** ptr:0xb781c244
buff[0]=5 - buff[1]=0 - buff[2]=0 - buff[3]=0 - buff[4]=W - buff[5]= - buff[6]= - buff[7]= - buff[8]= - buff[9]= - buff[10]= - buff[11]= - 

What has gone wrong in this chunk of code?

struct test{
  int mode;
  int id;
};

int func()
{   
int i, size;
struct test measure_msg;
char buff[20];
char* ptr;    

memset(&measure_msg, 0x00, sizeof(struct test));

ptr = buff;
fprintf(stderr, "**** ptr:%p\n", ptr);
sprintf(ptr, "%02d%02d", 50, 0);
ptr += 4;
size = 4;
size += sizeof(struct test);

fprintf(stderr, "**** ptr:%p\n", ptr);

measure_msg.id = 9999;
measure_msg.mode = 1111;

memcpy(ptr, &measure_msg, sizeof(struct test));
ptr += sizeof(struct test);

fprintf(stderr, "**** ptr:%p\n", ptr);

for (i=0; i<size; i++){
  fprintf(stderr, "buff[%d]=%c - ", i, buff[i]);
}

return 0;
}
twfx
  • 1,664
  • 9
  • 29
  • 56

3 Answers3

1

You're doing something strange but, look this:

sprintf(ptr, "%02d%02d", 50, 0);

You'll write a string to your buffer. Now buf will contains "5000". Please note that it won't contain the values 50 and 0 but their string representation!

Now when you copy the buffer to your struct you'll set its fields to these four bytes but they're not what you see when printing the string but its ASCII codes. Note that on this line:

fprintf(stderr, "buff[%d]=%c - ", i, buff[i]);

You print the content of the buffer as characters, '5' is stored as 0x35 (53 in decimal) then it'll be the content of the first byte of your structure (and so on).

If this is really what you want to do your code is exact (but you're playing too much with pointers, is it just a test?) but it's really really strange otherwise you're walking in the wrong direction to do what you need.

Adriano Repetti
  • 65,416
  • 20
  • 137
  • 208
0

The memcpy () call is working all right on my system (GCC/MinGW, Windows). You aren't getting the proper output because some of the "characters" getting copied into buff are non-printable.

Try

fprintf (stderr, "buff[%d]=%x - ", i, buff[i]);

instead.

The data will be stored as

buff [0]  = 0x35  /* ASCII for '5' */
buff [1]  = 0x30  /* ASCII for '0' */
buff [2]  = 0x30
buff [3]  = 0x30
buff [4]  = 0x57  /* as 1111 is 0x00000457 in hex */
buff [5]  = 0x04  /* stored in little endian convention */
buff [6]  = 0x00  /* and here size of int = 4 */
buff [7]  = 0x00
buff [8]  = 0x0F  /* as 9999 is 0x0000270F in hex  */
buff [9]  = 0x27
buff [10] = 0x00
buff [11] = 0x00 

But what are you trying to do anyway, by copying a struct to an array of chars?

  • Please note that the output will vary on different systems. Systems which use Intel architecture adopt "little-endian" convention for storing numbers, which means that the least significant byte (eg the 0x57 in 0x00000457) will be stored first and the most significant byte will be stored last. Also, in GCC size of the int data type is 4, and this may not be the case with other compilers. – Philips George John May 09 '12 at 07:49
0

When you memcpy your measure_msg to the buff you are copying int type values. After that, you are printing char type values. An int type value is composed by 4 bytes which may have no printing representation: i.e 33752069 int value, 0x02030405 in hex format, has 4 bytes that, once been printed like chars you get 0x02, 0x03, 0x04 and 0x05 char values.

Change your print masc to use int values and cast each buff[i] to int and your values will be printed.

fprintf(stderr, "buff[%d]=%d - ", i, (int)buff[i])
Tio Pepe
  • 3,071
  • 1
  • 17
  • 22