среда, 3 марта 2010 г.

[prog.c++] Пустой массив в структуре

Когда-то давным-давно, изучая программирование под Windows, встречал иногда вот такой фокус:

struct some_struct_t
   {
      int field_1;
      ...
      int field_N;
      char last_field[];
   };

Т.е. последним полем структуры является массив без объявления размерности. Использовалась эта штука для работы с данными переменной длины. Например, прочитали из файла/сокета блок данных, привели указатель на него к нашему типу, и пошли циклом по последнему полю:

char raw_data[ SOME_LIMIT ];
read_data( raw_data, sizeof( raw_data ) );
const some_struct_t * data =
      reinterpret_cast< const some_struct_t * >( raw_data );
for( size_t i = 0; i != data->field_K; ++i )
   if( XXX == data->last_field[ i ] )
      ...

Такой хак использовался когда-то в C, а потом достался в наследство C++. Ну и ладно бы, никогда к нему не прибегал. А на днях пришлось объяснять человеку, что когда он пишет вот так:

struct info_t
   {
      char * name[];
   };
info_t info;
for( size_t i = 0; i != ...; ++i )
   info.name[ i ] = new char[...];

то это, мягко говоря, не совсем правильно. Поскольку память под name никто не выделял, но наглым образом использует.

При этом я открыл для себя интересную штуку: оказывается, C++ компилятор под поле info_t::name вообще не выделяет места! Т.е. я думал, что при такой записи в info_t под поле name будет отведено место на один char*. Но нет! В Visual C++ 2003-2008 размер всей структуры info_t – всего один(!) байт (что и понятно, поскольку объектов с нулевым размером быть не должно). А вот в GCC 4.3.2 из cygwin-а размер info_t все-таки нулевой.

Вот такие дела. Век живи – век учись, дураком помрешь ;)

Отправить комментарий