При распределении памяти для массива с переменным размером я часто делаю что-то вроде этого:
struct array {
long length;
int *mem;
};
struct array *alloc_array( long length)
{
struct array *arr = malloc( sizeof(struct array) + sizeof(int)*length);
arr->length = length;
arr->mem = (int *)(arr + 1); /* dubious pointer manipulation */
return arr;
}
Затем я использую атрибут следующим образом:
int main()
{
struct array *arr = alloc_array( 10);
for( int i = 0; i < 10; i++)
arr->mem[i] = i;
/* do something more meaningful */
free( arr);
return 0;
}
Это работает и компилируется без предупреждений. Недавно, однако, я прочитал о строгом псевдониме. Насколько я понимаю, приведенный выше код является законным в отношении строгого сглаживания, поскольку доступ к памяти через int *
не является доступом к памяти через struct array *
. Действительно ли код нарушает строгие правила псевдонимов? Если да, то как его можно изменить, чтобы не сломать их?
Я знаю, что я мог бы распределять структуру и массив по отдельности, но тогда мне также нужно будет освобождать их отдельно, предположительно, в какой-то функции free_array
. Это означало бы, что я должен знать тип памяти, которую освобождаю, когда я ее освобождаю, что усложнит код. Вероятно, это будет медленнее. Это не то, что я ищу.