Почему memcmp возвращает -1, хотя и равен
Я сравниваю с использованием memcmp()
две переменные одной и той же структуры (в структуре есть объединение). Переменные находятся в двух массивах, и я запускаю цикл, где я делаю каждую итерацию memcmp(&arr1[i], &arr2[i], sizeof(arrtype))
,
При отладке я вижу, что memcmp возвращает -1, но, глядя на две переменные и их значения, я вижу, что переменные имеют одинаковые значения. Эти массивы обнуляются с помощью memset в начале.
- Так кто-нибудь знает, почему
memcmp
возвращает -1, а не 0? - Есть ли лучший способ сделать то, что мне нужно (сравнить два блока памяти)?
код:
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
сравнить два объекта может не получиться по трем причинам:
struct
может содержать байты заполнения, значения которых не контролируются.union
может содержать байты, которые не соответствуют байтам последнего сохраненного члена (например, дополнительные байты для одного из более длинных членов объединения).- Типы могут иметь одинаковые значения с разными представлениями (биты заполнения внутри типа, разные кодировки для +0 и –0 и т. Д.).
Если вы не предприняли шаги, чтобы убедиться, что ни одна из этих проблем не мешает сравнению через memcmp
тогда правильный способ сравнения двух структур - сравнивать их по элементам.