Comparing two memory areas can be very useful, memcmp() is the common C tool used to compare those two values. Also, depending on the type of data you wish to compare there is also a specific function for comparing two strings known as strncmp(). I plan to focus on memcmp for this article.
How do I use memcmp?
The memory compare function is provided by the gnu libc library and should be included via the string.h header file.
Its definition is:
int memcmp(const void *s1, const void *s2, size_t n);
There are a few important points to take away from this definition. Firstly, s1 and s2 are the respective memory areas to compare. The last argument is the number of bytes you wish to compare. So for instance, s1 could actually be 20 bytes, and s2 could be only two bytes. If you know that the first two bytes of s1 should be equivalent to the first two bytes of s2 you would specify to only compare those first two bytes. This gives the programmer the flexibility to shoot themselves in the foot. What if you decided you wanted to compare 5 bytes, well in this case memcmp would compare 5 bytes…but you would begin to compare 3 extra random bytes of s1 against s2. You may even run into a segmentation fault as you are potentially accessing memory not in scope. This is where the programmer should be right and know what and how big of a data set they are comparing.
Another important part is using the return value correctly. From the manual page:
The memcmp() function returns an integer less than, equal to, or greater than zero if the first n bytes of s1 is found, respectively, to be less than, to match, or be greater than the first n bytes of s2.
The take away from this is if you want two values to be equal, memcmp should be returning 0, any other value means they are not equal.
An example:
/* memcmp example */
#include <stdio.h>
#include <string.h>
int main ()
{
int res;
char b1[] = "abcDEF123";
char b2[] = "abcdef123";
res = memcmp(b1, b2, sizeof(b1));
if(res > 0)
fprintf(stdout, "result: %d, '%s' is greater than '%s'.\n",res,b1,b2);
else if(res < 0)
fprintf(stdout, "result: %d, '%s' is less than '%s'.\n",res,b1,b2);
else
fprintf(stdout, "result: %d, '%s' is the same as '%s'.\n",res,b1,b2);
return 0;
}
The result of running this program produces:
$ ./memcmp_test
result: -8192, 'abcDEF123' is less than 'abcdef123'.
This is because it compares the actual values, the ascii values of capital letters are smaller numerically than lower case.
How does memcmp work?
The actual implementation of memcmp is interesting. It accounts for the Endianness of your operating system and will swap Endianness when appropriate to ensure correct comparison is done. It then systematically compares each byte by byte validating if they are equal, if at any point they are not the function will return the result.
Click here to view the source code of memcmp.c