Этим утром мы нашли старый блок кода, который заставлял вызов библиотеки отказывать.
struct fred
{
int a;
int b;
int c;
};
fred fred[MAX_SIZE+1];
memset( fred, 0, sizeof(fred) * MAX_SIZE+1 );
Кажется, что sizeof (fred), возможно, был полным размером массива, а не размером структуры, поскольку это перезаписывало большую память.
То, что это скомпилировало, не предупреждая о нескольких различных системах, казалось нечетным.
Существует ли корректное семантическое для этого случая, где имя типа и имя переменной сталкиваются? или это своего рода неопределенное поведение? или просто дефект?
Номер один, не делайте этого, это сбивает с толку - но вы уже это обнаружили.
Переменная скрывает имя структуры, но вы все равно можете использовать struct fred
для ссылки на тип.
например.
fred fred[MAX_SIZE+1];
memset( fred, 0, sizeof(struct fred) * (MAX_SIZE+1) );
В качестве альтернативы, почему бы просто не использовать размер всего объекта. Таким образом, ваш вызов memset
устойчив к изменениям размера или типа массива. Вы можете сделать:
memset( fred, 0, sizeof fred );
Вы должны иметь круглые скобки при использовании идентификатора типа с sizeof
, но это не требуется при использовании объекта.
Разве это не должно быть sizeof ( fred) * (MAX_SIZE + 1), так как ваш массив имеет длину MAX_SIZE + 1?
Также имейте в виду, что если ваш сервер IIS сжатие вывода с помощью GZIP, то будет казаться, что все вызовы Response.Flush
игнорируются.
Это включено по умолчанию в IIS7 и Windows 7.
И, если вы тестируете с Fiddler, не забудьте включить режим Streaming, иначе Fiddler соберет сброшенный HTML-код и будет удерживать его до тех пор, пока соединение не будет установлено.
-1 21 --- 4780792- За исключением случаев, размер которых зависит от времени выполнения, типичный идиоматический способ использования memset
(а также memcpy
, malloc
] и т. д.) должно выполняться
memset(dst_ptr, 0, sizeof *dst_ptr);
или, что то же самое,
memset(&dst_object, 0, sizeof dst_object);
Как это должно было быть использовано и в этом случае
memset(&fred, 0, sizeof fred);
, и проблема с конфликтом имен не возникла бы. Вариант memset (fred, 0, sizeof fred)
также будет работать.
Когда вы определяете переменную, она скрывает имя типа, так что да, когда вы делаете sizeof (fred)
, вы получаем размер массива, а не размер структуры. в этом довольно легко убедиться, просто распечатав sizeof (fred)
.
Краткий ответ, однако, прост: «Не делай этого».