The C memcpy command provides mechanism to copy a set of bytes from location to another. It is quite similar to the strcpy function I wrote about earlier. The advantage of memcpy is that you can copy strings, or bytes, or data, or structures, or anything you want. The memcpy function does not discriminate.
The C memcpy function definition:
The definition of the memcpy function takes 3 arguments and is defined in the string.h header file.
#include <string.h> void *memcpy(void *dest, const void *src, size_t n); |
The first argument is the copy destination, the place where you want your data to be copied to. The second argument is the source data, and finally the third argument is the size of the area you want to be copied, defined as the number of bytes. The programmer also must ensure that the memory areas are not overlapping memory areas. Once the copy is complete the function will return a pointer to the start of the newly copied data area.
C memcpy Examples
What is a memcpy examples article without an example?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | #include <string.h> #include <stdio.h> int main(int argc, char **argv) { int i, j; i = 10; memcpy(&j, &i, sizeof(i)); fprintf(stdout, "J = %d\n", j); return 0; } |
This is just a silly example of using memcpy to copy the data at the address of i to the address of j. Thus the output from this function is:
$ ./main J = 10 |
Obviously memcpy is far more powerful than this and we could copy data from one structure to another quite easily:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | typedef struct { int i; char c; } memcpy_ex_t; int main(int argc, char **argv) { memcpy_ex_t a, b; a.i = 123; a.c = 'e'; fprintf(stdout, "Mem structure A: i = %u | c = %c\n", a.i, a.c); memcpy(&b, &a, sizeof(memcpy_ex_t)); fprintf(stdout, "Mem structure B: i = %u | c = %c\n", b.i, b.c); return 0; } |
The output from this you can probably guess:
$ ./main Mem structure A: i = 123 | c = e Mem structure B: i = 123 | c = e |
You could even use memcpy to clear your structure or element by simply creating a structure that is zeroed. For example if we modify the above program, and looking at lines 3, 14, 16 specifically for the additions:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | int main(int argc, char **argv) { memcpy_ex_t a, b, c = { 0 }; a.i = 123; a.c = 'e'; fprintf(stdout, "Mem structure A: i = %u | c = %c\n", a.i, a.c); memcpy(&b, &a, sizeof(memcpy_ex_t)); fprintf(stdout, "Mem structure B: i = %u | c = %c\n", b.i, b.c); memcpy(&b, &c, sizeof(memcpy_ex_t)); fprintf(stdout, "Mem structure B: i = %u | c = %c\n", b.i, b.c); return 0; } |
The output then becomes:
The output from this you can probably guess again: <pre lang="text"> $ ./main Mem structure A: i = 123 | c = e Mem structure B: i = 123 | c = e Mem structure B: i = 0 | c = |
Your imagination … and the compiler are probably your limits. Be careful though, especially with overlapping memory locations and the cost of doing memory copies is not cheap.
I have written earlier about using the C memset function.
Whenever possible I will try and use a switch statement instead of a set of if/else blocks. I do this for a few reasons:
- A switch construct is more easily translated into a jump (or branch) table. This can make switch statements much more efficient than if-else when the case labels are close together. The idea is to place a bunch of jump instructions sequentially in memory and then add the value to the program counter. This replaces a sequence of comparison instructions with an add operation.
- I find this provides cleaner in code, this is beneficial in the long run for legacy code and general upkeep.
One drawback of switch statements…at least I used to think was the ability to specify a range of values within each case statement. For example in an if statement you can do something like this:
if(x > 3 && x < 8) |
Is it possible to do so with a switch statement? It turns out if you are using GNU C then there is an extension that provides the ability to specify a range in your switch statements. An excerpt from the GCC help pages:
GNU C provides several language features not found in ISO standard C. (The -pedantic option directs GCC to print a warning message if any of these features is used.) To test for the availability of these features in conditional compilation, check for a predefined macro __GNUC__, which is always defined under GCC. |
Using the ellipsis in a switch statement
To utilize a range within a case of your switch statement you can use ellipsis or “…”. This informs the compiler to check the variable against two boundaries, a minimum and maximum. I thought I better test this extension with a small program before I actually use it. This program will read in one integer value using scanf then this value is sent to the switch statement which outputs a basic string identifying where the case has been matched.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #include <stdio.h> int main() { int x; scanf("%d", &x); switch (x) { case 1 ... 100: printf("1 <= %d <= 100\n", x); break; case 101 ... 200: printf("101 <= %d <= 200\n", x); break; default: break; } return 0; } |
The corresponding program output:
$ ./main 3 1 <= 3 <= 100 $ ./main 121 101 <= 121 <= 200 |
This little test program verifies that basic values will match their case equivalent. I would suggest compiling with -pedantic to ensure your compiler supports this extension before assuming it actually works. Pretty great nonetheless.



Latest Comments