我有一个结构,我想把它保存在连续的内存中,这样我就可以
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
因此,一些明显的解决办法不适用。