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, ¶m_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, ¶m_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, ¶m_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
Post a Comment