Почему memcmp возвращает -1, хотя и равен

Я сравниваю с использованием memcmp() две переменные одной и той же структуры (в структуре есть объединение). Переменные находятся в двух массивах, и я запускаю цикл, где я делаю каждую итерацию memcmp(&arr1[i], &arr2[i], sizeof(arrtype)),

При отладке я вижу, что memcmp возвращает -1, но, глядя на две переменные и их значения, я вижу, что переменные имеют одинаковые значения. Эти массивы обнуляются с помощью memset в начале.

  1. Так кто-нибудь знает, почему memcmp возвращает -1, а не 0?
  2. Есть ли лучший способ сделать то, что мне нужно (сравнить два блока памяти)?

код:

typedef struct type1 {
    int version;
    union {
            option1_t opt1;
            option2_t opt2;
    } union_t;
} type1_t;

typedef struct type0 {
    type1_t member1;
    type2_t member2;
    type3_t member3;
    type4_t member4;
    type5_t member;
} type0_t;


type0_t arr1[SIZE];
type0_t arr2[SIZE];

memset(arr1, 0, SIZE * sizeof(type0_t));
memset(arr2, 0, SIZE * sizeof(type0_t));

/* doing irrelevant stuff... */

/* get values into arr1, arr2 ... */


/* comparing both arrays in for loop*/
value = memcmp(&arr1[i], &arr2[i], sizeof(type0_t));

3 ответа

Скорее всего, вы читаете неопределенные значения (единичная память или память, перезаписанная для хранения неопределенных данных).

Например, вы можете получить доступ к члену профсоюза, который не был последним членом, который был написан. Даже если вы этого не сделаете, последний записанный член может быть меньше, чем общие экстенты объединения, что приведет к "неопределенным" данным за пределами этого размера.

struct X { 
    union {
         char field1;
         long long field2[10];
    };
};

struct X a,b;
a.field1 = 'a';
b.field1 = 'a';

Вы не можете ожидать a а также b сравнивать равные по битам, потому что вы никогда не инициализировали все биты в первую очередь (field2 имеет намного больше битов, превышающих field1)

--- В зависимости от значения неинициализированной памяти также вызывает неопределенное поведение.--- Не верно для C11

Если вы используете структуры, между полями-членами могут быть байты заполнения. Вы можете попытаться memeset вся структура до 0, прежде чем начать ее использовать.

С помощью memcmp сравнить два объекта может не получиться по трем причинам:

  1. struct может содержать байты заполнения, значения которых не контролируются.
  2. union может содержать байты, которые не соответствуют байтам последнего сохраненного члена (например, дополнительные байты для одного из более длинных членов объединения).
  3. Типы могут иметь одинаковые значения с разными представлениями (биты заполнения внутри типа, разные кодировки для +0 и –0 и т. Д.).

Если вы не предприняли шаги, чтобы убедиться, что ни одна из этих проблем не мешает сравнению через memcmpтогда правильный способ сравнения двух структур - сравнивать их по элементам.

Другие вопросы по тегам