c - Memcpy string as void pointer, incorrect read -


i'm trying create function puts buffer arbitrary types. think basic rpc. buffer looks

{ char opcode, uint32_t param1_size, param1, ... , uint32_t paramn_size, paramn } 

it seems working when extracting data buffer doesn't seem interpreting string correctly.

int enqueue_into_buf(char *buf, size_t buf_pos, const uint32_t param_len, const void *param) {      /* if param_len null, change opcode */     if(param_len == 0) {         memcpy( buf, param, 1 );         if(buf_pos == 0)             buf_pos++;         return buf_pos;     }      memcpy( buf + buf_pos, &param_len, sizeof(param_len) );     buf_pos += sizeof(param_len);      memcpy( buf + buf_pos, param, param_len );     buf_pos += param_len;      return buf_pos; }  int main(int argc, char *argv[]) {     char opcode;     uint32_t param_len, num_params, buf_size, buf_pos = 0, received_num;     char *buf, *temp;      char *input_string = "file01"; /* example string use parameter */     size_t input_size = 4, received_size; /* example variable use parameter */      opcode = '1'; /* opcode equals function 1 */     num_params = 2; /* number of parameters */      /* setting size of buffer sent on network */     buf_size = sizeof(opcode) + ( num_params * sizeof(uint32_t) ) + (strlen(input_string) * sizeof(char)) + sizeof(input_size);     buf = malloc( buf_size );      /* notice ampersand! */     buf_pos = enqueue_into_buf(buf, buf_pos, 0, &opcode);     buf_pos = enqueue_into_buf(buf, buf_pos, strlen(input_string), &input_string);     buf_pos = enqueue_into_buf(buf, buf_pos, sizeof(input_size), &input_size);      /* @ point, since inserted buffer,      buffer size , current buffer position should equal */      if(buf_pos == buf_size)         printf("calculated buffer size correctly , inserted correctly well. buffer size = %d\n", buf_size);      /** extract buffer **/     buf_pos = 0;      printf("opcode: %c\n", buf[buf_pos]);     buf_pos++;      memcpy(&received_num, buf + buf_pos, sizeof(uint32_t));     printf("size of parameter 1: %d\n", received_num);     buf_pos += sizeof(uint32_t);      temp = malloc(received_num + 1);     memcpy(temp, buf + buf_pos, received_num);     temp[received_num] = '\0';     printf("parameter 1: %s\n", temp);     buf_pos += received_num;      memcpy(&received_num, buf + buf_pos, sizeof(uint32_t));     printf("size of parameter 2: %d\n", received_num);     buf_pos += sizeof(uint32_t);      memcpy(&received_size, buf + buf_pos, sizeof(size_t));     printf("parameter 2: %d\n", received_size);     buf_pos += sizeof(size_t);      return 0; } 

edit: output of code:

calculated buffer size correctly , inserted correctly well. buffer size = 23 opcode: 1 size of parameter 1: 6 parameter 1: @  @ size of parameter 2: 8 parameter 2: 4 

i think i'm not copying data correctly buffer because, using same parameters (input_string = "file01", input_size = 4), code works...

    /* opcode */     buf[buf_pos] = opcode;     buf_pos++;      /* parameter 1 */     param_len = (strlen(input_string) * sizeof(char)); /* size of parameter 1 */      memcpy(buf + buf_pos, &param_len, sizeof(uint32_t));     buf_pos += sizeof(uint32_t);      //memcpy( buf + buf_pos, &input_string, (strlen(input_string) * sizeof(char)) );     strcat( buf + buf_pos, input_string );     buf_pos += strlen(input_string) * sizeof(char);       /* parameter 2 */     param_len = sizeof(input_size);      memcpy(buf + buf_pos, &param_len, sizeof(param_len)); /* same saying sizeof(uint32_t) */     buf_pos += sizeof(uint32_t);      memcpy(buf + buf_pos, &input_size, sizeof(input_size));     buf_pos += sizeof(input_size); 

edit: output of code:

calculated buffer size correctly , inserted correctly well. buffer size = 23 opcode: 1 size of parameter 1: 6 parameter 1: file01 size of parameter 2: 8 parameter 2: 4 

but don't want use strcat() because won't know kind of data type be. using memcpy incorrectly??

edit: put outputs of programs

you highlighted problem yourself:

/* notice ampersand! */ buf_pos = enqueue_into_buf(buf, buf_pos, 0, &opcode); buf_pos = enqueue_into_buf(buf, buf_pos, strlen(input_string), &input_string); 

you have declared

char *input_string = "file01"; 

so when pass &input_string enqueue_into_buf, copying strlen(input_string) bytes starting pointer input_string stored buffer.

usually, on 64-bit systems, 6 of 8 bytes of pointer value, on 32-bit systems 4 bytes of pointer plus 2 behind (invoking undefined behaviour).

but want copy string "file01" buffer, i.e. pointer points to, hence must not pass address of pointer pointer itself:

buf_pos = enqueue_into_buf(buf, buf_pos, strlen(input_string), input_string);                                                            // ^^ no address taken here! 

Comments

Popular posts from this blog

linux - Does gcc have any options to add version info in ELF binary file? -

android - send complex objects as post php java -

charts - What graph/dashboard product is facebook using in Dashboard: PUE & WUE -