Массив без указания размерности
От: Volodkya  
Дата: 10.03.11 11:58
Оценка: :)
Наткнулся в коде на структуру:


struct QPacket
{
#pragma pack(1)
    S32            len;
    U64            timestamp;
    bool        insertSilence;
    SocketStreamType*    socketStream;
    sockaddr_in sender;
    char        data[];
#pragma pack()
};


Пытаюсь работать с data:

delete[] p->data;
p->data[0] = new char[rtpPacketLen];
memcpy(p->data, rtpHeader, RTP_HEADER_LEN);


Ошибка. А так проходит:

delete[] p->data;
p->data[0] = (char) malloc(rtpPacketLen);
memcpy(p->data, rtpHeader, RTP_HEADER_LEN);


Туплю...не могу понять почему.
Re: Массив без указания размерности
От: 0x7be СССР  
Дата: 10.03.11 12:03
Оценка:
Здравствуйте, Volodkya, Вы писали:

V>Туплю...не могу понять почему.

Это нестандартное майкрософтовское расширение для языка.
Массив может быть так объявлен, если он — последний элемент в структуре.
Удобнее трактовать данные, которые лежат *после* структуры в памяти как часть массива.
Re[2]: Массив без указания размерности
От: Volodkya  
Дата: 10.03.11 12:09
Оценка:
Здравствуйте, 0x7be, Вы писали:

0>Здравствуйте, Volodkya, Вы писали:


V>>Туплю...не могу понять почему.

0>Это нестандартное майкрософтовское расширение для языка.
0>Массив может быть так объявлен, если он — последний элемент в структуре.
0>Удобнее трактовать данные, которые лежат *после* структуры в памяти как часть массива.

Спасибо! А как работать с такой структурой?...
Re[3]: Массив без указания размерности
От: Volodkya  
Дата: 10.03.11 12:11
Оценка:
Здравствуйте, Volodkya, Вы писали:

V>Здравствуйте, 0x7be, Вы писали:


0>>Здравствуйте, Volodkya, Вы писали:


V>>>Туплю...не могу понять почему.

0>>Это нестандартное майкрософтовское расширение для языка.
0>>Массив может быть так объявлен, если он — последний элемент в структуре.
0>>Удобнее трактовать данные, которые лежат *после* структуры в памяти как часть массива.

V>Спасибо! А как работать с такой структурой?...


Я имею в виду как отвести память под массив снова?
Преобразования не проходят или я неверно преобразовавыю.
Re[4]: Массив без указания размерности
От: Stanislav V. Zudin Россия  
Дата: 10.03.11 12:23
Оценка:
Здравствуйте, Volodkya, Вы писали:

V>>Спасибо! А как работать с такой структурой?...


V>Я имею в виду как отвести память под массив снова?

V>Преобразования не проходят или я неверно преобразовавыю.

Судя по всему, эта структура — заголовок пакета. Данные обычно следуют за заголовком непрерывно.
Тогда, если у тебя данных N байт, то выделяешь любым способом блок размером (N + sizeof(QPacket)),
кастишь его к указателю на QPacket, ну и работаешь.

std::vector<char> fufel(N + sizeof(QPacket), 0);
QPacket* pPacket = (QPacket*)&fufel[0];

for(int i = 0; i < N; ++i)
   pPacket->data[i] = bla-bla-bla;


Как-то так...
_____________________
С уважением,
Stanislav V. Zudin
Re[5]: Массив без указания размерности
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 10.03.11 13:48
Оценка:
Здравствуйте, Stanislav V. Zudin, Вы писали:

SVZ>Здравствуйте, Volodkya, Вы писали:


V>>>Спасибо! А как работать с такой структурой?...


V>>Я имею в виду как отвести память под массив снова?

V>>Преобразования не проходят или я неверно преобразовавыю.

SVZ>Судя по всему, эта структура — заголовок пакета. Данные обычно следуют за заголовком непрерывно.

SVZ>Тогда, если у тебя данных N байт, то выделяешь любым способом блок размером (N + sizeof(QPacket)),
SVZ>кастишь его к указателю на QPacket, ну и работаешь.

SVZ>
SVZ>std::vector<char> fufel(N + sizeof(QPacket), 0);
SVZ>QPacket* pPacket = (QPacket*)&fufel[0];

SVZ>for(int i = 0; i < N; ++i)
SVZ>   pPacket->data[i] = bla-bla-bla;
SVZ>


SVZ>Как-то так...

Лучше так не делать, можно отхватить на выравнивании.
Sic luceat lux!
Re[6]: Массив без указания размерности
От: Stanislav V. Zudin Россия  
Дата: 10.03.11 14:14
Оценка:
SVZ>>Как-то так...
K>Лучше так не делать, можно отхватить на выравнивании.

Что можешь предложить взамен?
_____________________
С уважением,
Stanislav V. Zudin
Re[6]: Массив без указания размерности
От: Pavel Dvorkin Россия  
Дата: 10.03.11 14:39
Оценка:
Здравствуйте, Kernan, Вы писали:

K>Лучше так не делать, можно отхватить на выравнивании.


Не будет тут проблем с выравниванием, если структура описана корректно. Корректно же означает, что массив без размерности выровнен на sizeof его элемента

struct S
{
int N;
unsigned data[];
};

В данном случае data имеет смещение 4, а поэтому выравнивание в порядке, то есть все остальные элементы массива тоже выровнены на 4.

А вот так нехорошо

struct S
{
short N;
unsigned data[];
};

поскольку data выровнен на 2, а не на 4.

В любом случае выровненность любого элемента этого массива, сколько бы их не было, такая же, как и у нулевого (то есть у описания). Но это условие должно быть выполнено всегда, даже если массив с размером. Так что есть размер или его нет — в плане выравнивания ни на что не влияет.
With best regards
Pavel Dvorkin
Re[7]: Массив без указания размерности
От: Stanislav V. Zudin Россия  
Дата: 10.03.11 14:48
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>А вот так нехорошо


PD>struct S

PD>{
PD> short N;
PD> unsigned data[];
PD>};

PD>поскольку data выровнен на 2, а не на 4.


На самом деле мы не можем сказать, на что будет здесь выровнен data. Ведь выравнивание определяется платформой, настройками проекта... Согласен?
Опять же, #pragma pack можно применить...
_____________________
С уважением,
Stanislav V. Zudin
Re[8]: Массив без указания размерности
От: Pavel Dvorkin Россия  
Дата: 10.03.11 14:51
Оценка:
Здравствуйте, Stanislav V. Zudin, Вы писали:

SVZ>Здравствуйте, Pavel Dvorkin, Вы писали:


SVZ>На самом деле мы не можем сказать, на что будет здесь выровнен data. Ведь выравнивание определяется платформой, настройками проекта... Согласен?


Независимо от того, на что выровнен data, все элементы этого массива выровнны на то же самое. Поэтому выделение памяти под N элементов этого массива никак не повлияет на выровненность.
With best regards
Pavel Dvorkin
Re[9]: Массив без указания размерности
От: BulatZiganshin  
Дата: 25.03.11 09:29
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Независимо от того, на что выровнен data, все элементы этого массива выровнны на то же самое. Поэтому выделение памяти под N элементов этого массива никак не повлияет на выровненность.


правильно:

QPacket *p;
int sizeof_QPacket = (char*)(p->data) — (char*)p;
malloc(sizeof_QPacket+N*sizeof(p->data[0]))
Люди, я люблю вас! Будьте бдительны!!!
Re[3]: Массив без указания размерности
От: Abyx Россия  
Дата: 25.03.11 09:37
Оценка:
Здравствуйте, Volodkya, Вы писали:

V>А как работать с такой структурой?...


Я использую это так

struct Foo
{
   int x;
   int y[];
};

Foo foo = {1, {2, 3}};
In Zen We Trust
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.