Сравнение данных заполнения
Сравнение данных заполнения.[1]
Эта проверка проверяет сравнение данных заполнения с памятью.
Сравнение данных заполнения в память происходит, когда вы используете memcmp функция для сравнения двух структур в целом. В процессе сравниваются бессмысленные данные, хранимые в заполнении структуры.
Для образца:
typedef struct structType {
char member1;
int member2;
//...
}myStruct;
myStruct var1;
myStruct var2;
//...
if(memcmp(&var1,&var2,sizeof(var1)))//Noncompliant
{
//...
}
Если представители структуры имеют различные типы данных, ваш компилятор вводит дополнительное заполнение для выравнивания данных в памяти. Пример заполнения см. в разделе Higher Estimate of Local Variable Size.
Содержимое этих дополнительных байтов заполнения бессмысленно. Стандарт C позволяет содержимое этих байтов быть неопределенным, предоставляя различным компиляторам широту для реализации собственного заполнения. Если вы выполняете байтовое сравнение структур с memcmp, вы сравниваете даже бессмысленные данные, хранящиеся в заполнении. Вы можете прийти к ложному выводу, что две структуры данных не равны, даже если их соответствующие представители имеют одинаковое значение.
Вместо сравнения двух структур в одной попытке сравните представителя структур по представителям.
Для эффективного кода запишите функцию, которая делает представитель сравнения по представителям. Используйте эту функцию для сравнения двух структур.
Можно использовать memcmp для байтового сравнения структур только в том случае, если известно, что структуры не содержат заполнения. Обычно, чтобы предотвратить заполнение, вы используете определенные атрибуты или прагмы, такие как #pragma pack. Однако эти атрибуты или прагмы не поддерживаются всеми компиляторами и делают вашу реализацию кода зависимой. Если ваши структуры содержат битовые поля, использование этих атрибутов или прагм не может предотвратить заполнение.
memcmp#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define fatal_error() abort()
typedef struct s_padding
{
char c;
int i;
unsigned int bf1:1;
unsigned int bf2:2;
unsigned char buffer[20];
} S_Padding ;
/* Function that guarantees safe access to the input memory */
extern int trusted_memory_zone(void *ptr, size_t sz);
int func(const S_Padding *left, const S_Padding *right)
{
if (!trusted_memory_zone((void *)left, sizeof(S_Padding)) ||
!trusted_memory_zone((void *)right, sizeof(S_Padding))) {
fatal_error();
}
if (0 == memcmp(left, right, sizeof(S_Padding)))
{
return 1;
}
else
return 0;
}В этом примере memcmp сравнивает байт за байтом две структуры, которые left и right указать на. Даже если значения, сохраненные в представителях структуры, одинаковы, сравнение может показать неравенство, если бессмысленные значения в байтах заполнения не совпадают.
Одной из возможных коррекций является сравнение отдельных представителей структуры.
Примечание
Можно сравнить целые массивы при помощи memcmp. Все представители массива имеют совпадающий тип данных. Заполнение байтов не требуется для хранения массивов.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define fatal_error() abort()
typedef struct s_padding
{
char c;
int i;
unsigned int bf1:1;
unsigned int bf2:2;
unsigned char buffer[20];
} S_Padding ;
/* Function that guarantees safe access to the input memory */
extern int trusted_memory_zone(void *ptr, size_t sz);
int func(const S_Padding *left, const S_Padding *right)
{
if (!trusted_memory_zone((void *)left, sizeof(S_Padding)) ||
!trusted_memory_zone((void *)right, sizeof(S_Padding))) {
fatal_error();
}
return ((left->c == right->c) &&
(left->i == right->i) &&
(left->bf1 == right->bf1) &&
(left->bf2 == right->bf2) &&
(memcmp(left->buffer, right->buffer, 20) == 0));
}| Решимость: Undecidable |
[1] Выдержки из стандарта «Техническая спецификация ISO/IEC TS 17961 - 2013-11-15» воспроизводятся с согласия АФНОР. Только оригинальный и полный текст стандарта, опубликованный AFNOR Editions - доступный через веб-сайт www.boutique.afnor.org - имеет нормативное значение.
1. Если смысл перевода понятен, то лучше оставьте как есть и не придирайтесь к словам, синонимам и тому подобному. О вкусах не спорим.
2. Не дополняйте перевод комментариями “от себя”. В исправлении не должно появляться дополнительных смыслов и комментариев, отсутствующих в оригинале. Такие правки не получится интегрировать в алгоритме автоматического перевода.
3. Сохраняйте структуру оригинального текста - например, не разбивайте одно предложение на два.
4. Не имеет смысла однотипное исправление перевода какого-то термина во всех предложениях. Исправляйте только в одном месте. Когда Вашу правку одобрят, это исправление будет алгоритмически распространено и на другие части документации.
5. По иным вопросам, например если надо исправить заблокированное для перевода слово, обратитесь к редакторам через форму технической поддержки.