简体   繁体   中英

How the memcmp on structure with integer variable in c lang compares. Result is not as expected

I have a structure with integer, I am comparing the struct by using memcmp, I don't want to use other memthods.

   #include <stdio.h>
   #include <string.h>

   typedef struct Foo 
   {
      int d;
   } Foo;

   int main(int argc, const char * argv[])
   {
      Foo one, two;
      int result;
   
      memset(&one,0,sizeof(Foo));
      memset(&two,0,sizeof(Foo));
    
      one.d = 1022;
      two.d = 1024;
    
      result = memcmp((void*)&one, (void*)&two, sizeof(Foo));
      printf("comp with assignment %d\n",result);
    
      if (result == 0) printf("Arrays are the same\n");
    
      return 0;
   }

memcmpa should return -1, but it returns 1. why? memcmp woth one.d = 1022 and two.d = 1023 will return correct value. why is so?

If you add two printf s in your code:

   typedef struct Foo 
   {
      int d;
   } Foo;

   int main(int argc, const char * argv[])
   {
      Foo one, two;
      int result;
   
      memset(&one,0,sizeof(Foo));
      memset(&two,0,sizeof(Foo));
    
      one.d = 1022;
      two.d = 1024;

      printf("%04x %04x\n", one.d, two.d);
    
      result = memcmp((void*)&one, (void*)&two, sizeof(one));
      printf("comp with assignment %d\n",result);
    
      if (result == 0) printf("Arrays are the same\n");
    
      return 0;
   }

Result:

03fe 0400
comp with assignment 1

You will see that the first byte of one is 0xfe and the first byte of two is 0x00 (they are in opposite order as most modern machines are little endioan) So 0xfe > 0x00 and memcmp returns 1

It compares bytes , not int s:

memcmp - This function reads object representations, not the object values, and is typically meaningful for byte arrays only: struct s may have padding bytes whose values are indeterminate,

Look at how an int looks at byte level and you'll see it more clearly. It can be stored with the most significant byte first or last - and the result of memcmp will depend on that.

You can create your own memcmp_debug for this purpose.

Example:

int memcmp_debug(const void *vpa, const void *vpb, size_t len) {
    const unsigned char *a = vpa, *b = vpb;

    puts("comparing these:");
    for(size_t i = 0; i < len; ++i) {
        printf("%2d %02X %02X\n", i, a[i], b[i]);
    }

    puts("\ncomparing:");
    for(unsigned i = 0; i < len; ++i) {
        int result = (int)a[i] - (int)b[i];
        printf("%2d %02X %02X  =>  %d\n", i, a[i], b[i], result);
        if(result) return result;
    }
    return 0;
}

Possible output:

comparing these:
 0 FE 00
 1 03 04
 2 00 00
 3 00 00

comparing:
 0 FE 00  =>  254

.. and here it returned on the first byte compared (the least significant byte on my machine) and returned a positive value just like it did for you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM