2010-12-30 3 views

ответ

15

Одним словом, да.

В принципе, как C99, чтобы сделать это с flexible array member:

uint32 words[]; 

Некоторые компиляторы предварительно C99 позволяют уйти с:

uint32 words[0]; 

Но путь, чтобы гарантировать ее работу по всем компиляторам:

uint32 words[1]; 

И тогда, независимо от того, как это объявлено, вы можете выделить объект wit ч:

Bitmapset *allocate(int n) 
{ 
    Bitmapset *p = malloc(offsetof(Bitmapset, words) + n * sizeof(p->words[0])); 
    p->nwords = n; 
    return p; 
} 

Хотя для достижения наилучших результатов следует использовать size_t вместо int.

+0

Спасибо. Так будет ли это сложное распределение иметь проблемы для объекта прокладки структуры, скажем, если переданное n является нечетным числом? – Oxdeadbeef

+0

@ Oxdeadbeef - Да, я полагаю. Вы не будете хранить массив из них в непрерывной памяти. Если вам нужен массив, вам, вероятно, будет лучше использовать «Bitmapset» a [20] = {NULL}; 'или' Bitmapset ** a = malloc (20 * sizeof * a); '. –

+1

Синтаксис 'offsetof (Bitmapset, words [n])' является расширением (которое, как правило, поддерживается большинством компиляторов). Для строгого соответствия используйте 'offsetof (Bitmapset, words) + n * sizeof (p-> words [0])'. – Jed

6

Обычно это разрешает идиоматический доступ к экземплярам структур переменной длины. Учитывая ваш пример, во время выполнения, вы можете иметь Bitmapset, который заложен в памяти, как это:

----------------- 
| nwords | 3 | 
| words[0] | 10 | 
| words[1] | 20 | 
| words[2] | 30 | 
----------------- 

Таким образом, вы в конечном итоге с выполнения переменной числа uint32 «висит от» конца вашей структуры, но доступны так, как если бы они были определены внутри структуры. Это в основном (ab), используя тот факт, что C не проверяет границы массива во время выполнения, чтобы вы могли писать код:

for (int i = 0; i < myset.nwords; i++) { 
    printf("%d\n", myset.words[i]); 
} 
+0

спасибо. но в чем преимущество над использованием слов uint32 *? – Oxdeadbeef

+5

Не будет работать так же. Если вы это сделали, слова [2] скажут «следуйте указателю, расположенному в поле« слова »структуры, затем перейдите еще 2 * 8 == 16 байт и получите доступ к памяти там». Вы должны (например,,) malloc() отдельная область памяти, содержащая массив слов в куче, и это может повлиять на производительность и простоту использования. –

Смежные вопросы