Home > Software design >  Are there alternatives to memcpy when I have allocated too much buffer space?
Are there alternatives to memcpy when I have allocated too much buffer space?

Time:10-22

Imagine this simple piece of code. Here I allocated too much memory and I want to only keep the right amount of bytes (to for example send over the network).

char src[100];
    
// Some code that only fills the buffer with 20 bytes
size_t sz = 20;
    
char dest[sz];
memcpy(dest, src, sz);

Is there a better way to do this instead of using memcpy?

CodePudding user response:

Here I allocated too much memory and I want to only keep the right amount of bytes (to for example send over the network).

You don't need to resize the memory to send the right amount. fwrite takes how big your elements are and how much to send. Perhaps you're always using the size of the buffer to determine what to send like fwrite(src, size(src), 1, fp);.

Instead, only send what you need.

// Only send the first 20 bytes of src.
fwrite(src, 20, 1, fp);

I actually need the optimization since I am working with resource constrained (IoT) devices.

You're not saving any memory, you're using more memory.

Because you're using automatic memory src lives on until the end of the block. If you copy src to dest you're using 120 bytes instead of 100.

CodePudding user response:

OP's code is OK, when compiler supports variable length arrays and array needs did not grow.

char src[100];
size_t sz = 20;
char dest[sz]; // VLA
// memcpy(dest, src, sz);
memcpy(dest, src, sizeof dest); // Better when not a char array

In C, once an array is defined, its size cannot change. So src[] must remain with 100 elements, but dest[] may differ.


Alternative: memory allocation via *alloc() and friends.

size_t sz = 100;
char *src = malloc(sizeof *src * sz);
if (src == NULL) Handle OutOfMemory();

sz = 20; 
char *src_new = realloc(src, sizeof *src_new * sz);
if (src_new == NULL) Handle OutOfMemory();

src = src_new;
// memcpy() not needed as copying done by realloc()
// With a size increase, new elements are indeterminate.

free(src);
src = NULL;

A 3rd approach is to do more work and determine size needed before defining the array.

int size = snprintf(NULL, 0, "%s %g %d", some_string, some_double, some_int);
assert(size >= 0);
char s[size   1u];

size = snprintf(s, sizeof s, "%s %g %d", some_string, some_double, some_int);
assert(size >= 0 && (unsigned) size < sizeof s);

CodePudding user response:

  1. If your object has static or automatic storage class its size cannot be changed runtime.

Is there a better way to do this instead of using memcpy?

memcpy novadays is the most efficient way of copying the data. Modern compilers know this function very well and usually replace the call to it with inlined efficient code.

example: https://godbolt.org/z/1GKea7Mon

  •  Tags:  
  • c
  • Related