0

I am working with sending data to and from a client/server application. I have created my own header scheme. This is the flow I am in question about:

char *data = returnmydata();
int one = 1;
int two = 2;
int three = 3;

So what happens is I have a char buffer that contains all my data. But I need to append to the front of this data my one, two, and three integers which is used to let the other side know how to handle the data.

Instead of allocating enough at the start for the 3 header items, is it possible to reallocate an addition 12 bytes and move the start of the data to data+12?

I currently just memcpy the 3 integers at the start then offset the data +12. However I think my code would be better if I could just pass a struct that contains the 3 ints and a pointer to the data. Then I can use this function to create the full data buffer with the headers in it.

Another option is to alloc another buffer memcpy the 3 integers to the front, and then memcpy the data to the new buffer. However I would like to keep memory usage low.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
xf900
  • 35
  • 4
  • 1. `realloc()` or 2. new allocation, copy, free old pointer. – i486 Mar 21 '22 at 16:39
  • realloc() doesn't add the space to the front of the data though right? – xf900 Mar 21 '22 at 16:40
  • 1
    Re “Instead of allocating enough at the start for the 3 header items…”: Why are you ruling that out? – Eric Postpischil Mar 21 '22 at 16:45
  • 1
    How are you transmitting the data? It is likely the entire message does not have to be sent via a single call. You could call the write or transmit routine once with the three `int` (or three times each with one `int`) and then once with the remaining data to be sent. Then you do not need to deal with fiddling with memory or allocating extra at all. (The write/transmit routine will copy the data into its buffer.) – Eric Postpischil Mar 21 '22 at 16:46
  • FYI, “append to the front” is called “prepend” or “prefix”. – Eric Postpischil Mar 21 '22 at 16:47
  • 1
    Instead of combining all data into one buffer, what about using [`writev` & friends](https://man7.org/linux/man-pages/man2/readv.2.html)? – Gerhardh Mar 21 '22 at 16:47
  • Is there any alignment requirement to the data? If `returnmydata` is returning an address that, in spite of its `char *` or `void *` type, needs to be more strictly aligned than a four-byte `int`, then moving the data 12 bytes can cause problems. – Eric Postpischil Mar 21 '22 at 16:48
  • _I think my code would be better if I could just pass a struct that contains the 3 ints and a pointer to the data_. What's stopping you? If you have the same amount of data every time, you could add that size to the struct at compile time (if not, where is the size of the data?). _I would like to keep memory usage low_. Are you on an embedded system with a small footprint? If not, this isn't much of a concern. Even low-end PCs these days have GBs of memory. – yano Mar 21 '22 at 17:09

1 Answers1

-1

Use functions realloc and memmove.

If the size of the initially allocated buffer is equal to some value N then you can write

char *tmp = realloc( data, N + 12 );

if ( tmp != NULL )
{
    data = tmp;
    memmove( data + 12, data, N );
    // then you can insert some values in the first 12 bytes of the allocated buffer
}
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335