c - 将成员地址分配给结构中的其他成员

标签 c pointers struct

以下在 C 中安全吗?

struct Buffer {
  size_t size;
  int8_t *storage;
};

struct Context {
  struct Buffer buffer;
  int8_t my_storage[10];
};

struct Context my_context = {
  .buffer = {
    .size = 0,
    .storage = my_context.my_storage,
  },
  .my_storage = {0},
};

我正在使用微 Controller ,我不想必须使用 malloc。此外,对我来说,收集结构中的所有内容比将存储作为上下文外部的单独变量更好。

[编辑1] 我已经测试过它并且它可以编译和工作,因为指向 my_context.my_storagemy_context.buffer.storage 的指针是相同的,gcc (Debian 4.7 .2-5) Linux 上的 4.7.2 ... 3.2.0-4-amd64 #1 SMP Debian 3.2.65-1+deb7u2 x86_64 GNU/Linux

[编辑2] 在后来被删除的答案中,我提到了 C99 标准第 6.7.8-19 节“初始化应按初始化列表顺序进行......”这是否意味着

struct Context my_context = {
  .my_storage = {0},
  .buffer = {
    .size = 0,
    .storage = my_context.my_storage,
  },
};

能保证安全吗?我是这样理解的。

[编辑3] 下面是一个完整的工作示例。

#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>

struct Buffer {
  size_t size;
  int8_t *storage;
};

struct Context {
  struct Buffer buffer;
  int8_t my_storage[10];
};

struct Context my_context = {
  .buffer = {
    .size = 0,
    .storage = my_context.my_storage,
  },
  .my_storage = {0},
};

int
main(void)
{
  printf ("ptr points to: %" PRIXPTR "\n", (uintptr_t)my_context.buffer.storage);
  printf ("storage is at: %" PRIXPTR "\n", (uintptr_t)my_context.my_storage);
}

>> ./test
ptr points to: 600950
storage is at: 600950

最佳答案

是的,这很好。假设 my_context 有自动存储持续时间,它的生命周期从进入关联 block 开始,并且在它的生命周期中它有一个常量地址(6.2.4 对象的存储持续时间/2 ). (如果它具有静态或线程存储持续时间,则其生命周期分别延长整个程序或线程的持续时间)。

由此可见,my_context.my_storagemy_context 的生命周期内也有一个常量地址,因此将其地址(通过数组到指针衰减)用于初始化my_context.buffer.storage 将给出与 my_context 初始化完成后相同的值。

另请注意,my_context范围从其声明完成的点开始,即在初始化程序的 = 之前,因此在其初始化程序中引用它也可以。

关于c - 将成员地址分配给结构中的其他成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30162131/

相关文章:

c - 寻找有关死锁场景的指导

c - 一般指针问题

java - 实现 Arp 扫描

c - 为什么无论我输入什么内容,我的 C 程序都会打印出相同的输出?

c++ - C++ 中的结构偏移量和指针安全

c - "int * * k"是什么意思?

c++ - 我们可以在什么时候使用带指针的空参数?

C++数据结构声明

c - gcc 对初始化程序中大括号的提示(嵌套结构)

gcc - 如何强制 GCC 将 128 位/256 位结构作为 xmm/ymm 寄存器中的函数参数传递?