C 中是否可以动态分配结构体数组?
在我正在从事的一个项目中,我发现自己创建了许多小型手写结构数组,这些数组需要存储在动态分配的内存中(主要用于在从文件导入之前使用小型数据集进行测试)。有一个非常好的语法来初始化静态结构数组,如下面的 vec2,但我一直在使用下面使用 memcpy 的解决方案 vec3 >。
vec4
显示了我想要做的事情,但显然它不太有效。即使匿名数组 *((struct vec2d[]) { {1, 2}, {3, 4}, {5, 6} })
包含三个 strut vec2d
s,当它(和 LHS)被取消引用时,它们变成 (struct vec2d)
,因此只有第一个 struct vec2d
被分配给分配的内存vec4。
有什么方法可以让我纯粹作为一项作业来完成这个任务,而不使用 memcpy 吗?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct vec2d
{
double x,y;
};
//void print_vec2d(char *, struct vec2d *);
void print_vec2ds(char *label, size_t count, struct vec2d *vec)
{
for (size_t i = 0; i < count; i++)
{
printf("%s (%li of %li): (%f, %f)\n", label, i + 1, count, (vec[i]).x, (vec[i]).y);
}
printf("\n");
}
int
main(int c, char **a)
{
// nice and concise syntax
struct vec2d vec2[3] =
{
{12, 34},
{56, 78},
{90, 112}
};
print_vec2ds("vec2", 3, vec2);
// a little bulky to have to wrap it all in a call to memcpy
struct vec2d *vec3 = calloc(3, sizeof(struct vec2d));
memcpy(vec3, (struct vec2d[])
{
{1, 2},
{3, 4},
{5, 6}
}, 3*sizeof(struct vec2d));
print_vec2ds("vec3", 3, vec3);
// this doesn't (and shouldn't) work, but I like the syntax :)
struct vec2d *vec4 = calloc(3, sizeof(struct vec2d));
*vec4 = *((struct vec2d[])
{
{1, 2},
{3, 4},
{5, 6}
});
print_vec2ds("vec4", 3, vec4);
}
程序输出,显示最后一个分配如何不起作用:
vec2 (1 of 3): (12.000000, 34.000000)
vec2 (2 of 3): (56.000000, 78.000000)
vec2 (3 of 3): (90.000000, 112.000000)
vec3 (1 of 3): (1.000000, 2.000000)
vec3 (2 of 3): (3.000000, 4.000000)
vec3 (3 of 3): (5.000000, 6.000000)
vec4 (1 of 3): (1.000000, 2.000000)
vec4 (2 of 3): (0.000000, 0.000000)
vec4 (3 of 3): (0.000000, 0.000000)
顺便说一句,我发现可以将分配的 LHS 和 RHS 转换为保存我想要分配的数据量的结构的指针类型:
struct bad {double a,b,c,d,e,f};
struct vec2d *vec5 = calloc(3, sizeof(struct vec2d));
*((struct bad*) vec5) = *((struct bad*) ((struct vec2d[])
{
{1, 2},
{3, 4},
{5, 6}
}));
print_vec2ds("vec5", 3, vec5);
哪个“有效” ,但它需要定义一个精确长度的结构,这并不是真正的解决方案......
In a project I'm working on, I find myself creating a lot of small, hand-written arrays of structs that need to be stored in dynamically allocated memory (mostly for testing with small datasets before importing from a file). There's a really nice syntax to initialize a static array of structs, as vec2
below, but I've been using the solution vec3
below that uses memcpy
.
vec4
shows sort of what I'd like to be able to do, but obviously it doesn't quite work. Even though the anonymous array *((struct vec2d[]) { {1, 2}, {3, 4}, {5, 6} })
contains three strut vec2d
s, when it (and the LHS) are dereferenced, they become (struct vec2d)
, so only the first struct vec2d
gets assigned to the memory allocated at vec4
.
Is there some way for me to accomplish this purely as an assignment, without using memcpy?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct vec2d
{
double x,y;
};
//void print_vec2d(char *, struct vec2d *);
void print_vec2ds(char *label, size_t count, struct vec2d *vec)
{
for (size_t i = 0; i < count; i++)
{
printf("%s (%li of %li): (%f, %f)\n", label, i + 1, count, (vec[i]).x, (vec[i]).y);
}
printf("\n");
}
int
main(int c, char **a)
{
// nice and concise syntax
struct vec2d vec2[3] =
{
{12, 34},
{56, 78},
{90, 112}
};
print_vec2ds("vec2", 3, vec2);
// a little bulky to have to wrap it all in a call to memcpy
struct vec2d *vec3 = calloc(3, sizeof(struct vec2d));
memcpy(vec3, (struct vec2d[])
{
{1, 2},
{3, 4},
{5, 6}
}, 3*sizeof(struct vec2d));
print_vec2ds("vec3", 3, vec3);
// this doesn't (and shouldn't) work, but I like the syntax :)
struct vec2d *vec4 = calloc(3, sizeof(struct vec2d));
*vec4 = *((struct vec2d[])
{
{1, 2},
{3, 4},
{5, 6}
});
print_vec2ds("vec4", 3, vec4);
}
program output, showing how last assignment doesn't work:
vec2 (1 of 3): (12.000000, 34.000000)
vec2 (2 of 3): (56.000000, 78.000000)
vec2 (3 of 3): (90.000000, 112.000000)
vec3 (1 of 3): (1.000000, 2.000000)
vec3 (2 of 3): (3.000000, 4.000000)
vec3 (3 of 3): (5.000000, 6.000000)
vec4 (1 of 3): (1.000000, 2.000000)
vec4 (2 of 3): (0.000000, 0.000000)
vec4 (3 of 3): (0.000000, 0.000000)
Incidentally, I discovered that it's possible to cast the LHS and RHS of the assignment into the pointer type of a struct which holds the amount of data I want to assign:
struct bad {double a,b,c,d,e,f};
struct vec2d *vec5 = calloc(3, sizeof(struct vec2d));
*((struct bad*) vec5) = *((struct bad*) ((struct vec2d[])
{
{1, 2},
{3, 4},
{5, 6}
}));
print_vec2ds("vec5", 3, vec5);
which "works", but it requires a struct of the precise length to be defined, which isn't really a solution…
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为需要在编译时知道大小才能进行纯粹的赋值。否则,memcpy() 是一个很好的解决方案。如果你想让它更简单一点,你可以这样做:
I believe that the size needs to be known at compile-time in order to do a pure assignment. Otherwise
memcpy()
is a fine solution. If you want to make it a bit simpler you could maybe do something like: