У меня есть структура, которую я хотел бы хранить в смежной памяти, чтобы я мог иметь возможность memcpy
всей структуры и т. Д. Однако моя структура содержит массив переменной длины. Теперь эта длина будет фиксированной на время выполнения программы , но во время компиляции она неизвестна. Можно ли обойти это, перераспределив память после структуры, чтобы освободить место длямассив?
Так что, если бы я начал с
struct license_plate{
char issuing_province_territory_code [2];
char* number;
}
, мне потребовался бы отдельный malloc
для number
, поэтому я подумал сделать следующее
struct license_plate_v2 {
char issuing_province_territory_code [3];
char number[1];
}
и выделите его таким образом
size_t sizeof_license_plate_v2( int number_length ){
return sizeof(struct license_plate_v2) + number_length * sizeof(char);
}
struct license_plate_v2* malloc_license_plate_v2( int number_length ){
return malloc( sizeof_license_plate_v2( number_length ) );
}
, а затем сможете перебирать массив, например
struct license_plate_v2* index_license_plate_v2( struct license_plate_v2 *arr, int index, int plate_num_len ){
return arr + index * sizeof_license_plate_v2(plate_num_len);
}
void print_all( struct license_plate_v2* plates, int num_of_plates, int plate_num_len ){
for( int plate_index = 0; plate_index < num_of_plates; plate_index++ ){
struct license_plate_v2* plate = index_license_plate_v2( plates, plate_index, plate_num_len );
printf( "where: %s, plate: %s\n", plate->issuing_province_territory_code, plate->number );
}
}
Это допустимый C?Это гарантированно работает или я использую неопределенное поведение?Есть ли проблема с байтовым выравниванием, если массив состоит из структур?Есть ли термин для этого?Это правильный путь для достижения такого эффекта?
Кажется, что работа:
#include <stdlib.h>
int main( int argc, char** argv ) {
//these values could have from from argv for example
int num_len = 7;
struct license_plate_v2 *arr = malloc( 4 * sizeof_license_plate_v2(num_len) );
struct license_plate_v2 *arr_0 = arr + 0 * sizeof_license_plate_v2(num_len);
memcpy( arr_0->issuing_province_territory_code, "ON" , 3 * sizeof(char) );
memcpy( arr_0->number , "BFKK281" , (num_len+1) * sizeof(char) );
struct license_plate_v2 *arr_1 = arr + 1 * sizeof_license_plate_v2(num_len);
memcpy( arr_1->issuing_province_territory_code, "ON" , 3 * sizeof(char) );
memcpy( arr_1->number , "BYTR741" , (num_len+1) * sizeof(char) );
struct license_plate_v2 *arr_2 = arr + 2 * sizeof_license_plate_v2(num_len);
memcpy( arr_2->issuing_province_territory_code, "ON" , 3 * sizeof(char) );
memcpy( arr_2->number , "CAAA224" , (num_len+1) * sizeof(char) );
struct license_plate_v2 *arr_3 = arr + 3 * sizeof_license_plate_v2(num_len);
memcpy( arr_3->issuing_province_territory_code, "ON" , 3 * sizeof(char) );
memcpy( arr_3->number , "CASD431" , (num_len+1) * sizeof(char) );
print_all( arr, 4, 7 );
free( arr );
}
PS - это упрощенный пример, чтобы проиллюстрировать вопрос, проблема реального мира включает в себя что-то вроде миллионов мест с тысячами (запуститьно не компилируйте постоянную времени) точек данных, каждая из которых является структурой, а не char
, поэтому некоторые очевидные обходные пути не применяются.