c - 访问结构体内部的结构体指针数组

标签 c

我正在尝试在结构中分配 char 数组值并检索数据,但在检索时遇到一些问题。

struct first {
    int a;
    int b; 
};

struct second {
    int c;
    int d;
    struct first * f_t[2]; 
};

int main()
{
    struct second *p;
    char a[24] = {1, 0, 0, 0, 
                  2, 0, 0, 0, 
                  3, 0, 0, 0, 
                  4, 0, 0, 0,
                  5, 0, 0, 0,
                  6, 0, 0, 0};
    p = (struct second *)a;
    p->f_t[0] = (struct first *) (a + 8);
    p->f_t[1] = (struct first *) (a + 16);
    printf("%d %d %d %d %d %d", 
         p->c, p->d, p->f_t[0]->a, p->f_t[0]->b, p->f_t[1]->a, p->f_t[1]->b);
}

输出:

1 2 1245008 1245016 1245024 6

前两个值正确(12),但其余的似乎是一些垃圾值。

请帮助识别一些错误的初始化或其他相同的方法。

最佳答案

首先,永远不要假设结构中的填充。它的工作相当可靠,但技术上是未定义的行为。

更重要的是,您违反了严格的别名规则。编译器假设您永远不会使用不同类型的指针(在本例中为 struct first*char*)访问同一内存位置。您可以使用 -fno-strict-aliasing 来解决这个问题,或者使用 union 来进行类型双关,就像通常所说的那样。去 here了解更多信息。

此代码的更正确版本是 -

#include <stdio.h>
#include <stdlib.h>
#include <alloca.h>
#include <string.h>

struct first {
  int a;
  int b; 
};
struct second {
  int c;
  int d;
  struct first * f_t[2]; 
};
int main()
{
  struct second *p;
  char a[24] =        {1,0,0,0,2,0,0,0,3,0,0,0,4,0,0,0,5,0,0,0,6,0,0,0};
  p = alloca(sizeof(struct second));
  memset(p, 0, sizeof(struct second));
  memcpy(p, a, sizeof(int)*2);
  p->f_t[0]= alloca(sizeof(struct first));
  p->f_t[1]= alloca(sizeof(struct first));
  memset(p->f_t[1], 0, sizeof(struct first));
  memset(p->f_t[0], 0, sizeof(struct first));
  memcpy(p->f_t[0], a + 8, sizeof(struct first));
  memcpy(p->f_t[1], a + 16, sizeof(struct first));
  printf("%d %d %d %d %d %d",p->c,p->d,p->f_t[0]->a,p->f_t[0]->b,p->f_t[1]->a,p->f_t[1]->b);

}

注意:使用 alloca() 是不好的做法。除非您知道自己在做什么,否则不要使用它。在这里很好,因为它只是在堆栈上分配的一个小结构,但通常远离它并使用 malloc() 或仅使用局部变量。

这在技术上仍然属于未定义的行为,因为我们假设结构如何填充,这是特定于实现的,但大多数平台使用自对齐数据类型,并且在使用正确对齐的结构时速度要快得多,因此很容易猜测。欲了解更多信息,请访问here我仍然强烈建议不要这样做,因为这是未定义的行为,而且很容易搞砸。

此外,下次请确保提供最小、完整且可编译的示例。

关于c - 访问结构体内部的结构体指针数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51671823/

相关文章:

C:为什么我的库中的全局变量不会更新? (使用 ALSA 库)

c - 有没有办法在 POSIX C 中做到这一点?

c - 需要帮助理解 while ((status = SOME_STATUS == FunctionName(params)))

c - 分页代码片段

c - float 的三向比较

c - 在 C 中打开文件,但我不知道如何获取文件的宽度和高度

CodeLite 构建选项未突出显示 : can't compile and test code (Ubuntu 11. 10)

CS50(2019)习题集 "Filter": "blur" somehow not working correctly

你能从连接的 TCP 套接字中确定源 IP 和端口吗?

c - 在二叉树中插入一个元素