C 中是否可以动态分配结构体数组?

发布于 2025-01-10 06:25:43 字数 2241 浏览 0 评论 0原文

在我正在从事的一个项目中,我发现自己创建了许多小型手写结构数组,这些数组需要存储在动态分配的内存中(主要用于在从文件导入之前使用小型数据集进行测试)。有一个非常好的语法来初始化静态结构数组,如下面的 vec2,但我一直在使用下面使用 memcpy 的解决方案 vec3 >。

vec4 显示了我想要做的事情,但显然它不太有效。即使匿名数组 *((struct vec2d[]) { {1, 2}, {3, 4}, {5, 6} }) 包含三个 strut vec2ds,当它(和 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 vec2ds, 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

话少心凉 2025-01-17 06:25:43

有什么方法可以让我纯粹作为一项作业来完成这个任务,而不使用 memcpy 吗?

我认为需要在编译时知道大小才能进行纯粹的赋值。否则,memcpy() 是一个很好的解决方案。如果你想让它更简单一点,你可以这样做:

  struct vec2d vec2[3] =
  {
    {12, 34},
    {56, 78},
    {90, 112}
  };

  struct vec2d *vec3 = malloc(sizeof(vec2));
  memcpy(vec3, vec2, sizeof(vec2));

Is there some way for me to accomplish this purely as an assignment, without using 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:

  struct vec2d vec2[3] =
  {
    {12, 34},
    {56, 78},
    {90, 112}
  };

  struct vec2d *vec3 = malloc(sizeof(vec2));
  memcpy(vec3, vec2, sizeof(vec2));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文