在结构中初始化数组

Initializing arrays in struct

所以我决定用 C 为微控制器(如果重要的话是 PIC32)编写我自己的大整数库,但我遇到了一个我不明白的奇怪问题。当代码为 运行 时,big_int_t 结构 ab 位于不同的内存位置,但 a->bytesb->bytes 似乎位于相同的位置(通过打印他们的指针确认)。在 b->bytes 中设置值也会更改 a->bytes 中的值。在下面的 main 函数中,打印任一结构的 bytes 数组中的第一个元素显示 41。我做错了什么吗?

#include <stdint.h>
#include <stdio.h>

typedef struct {
  uint8_t size;
  uint8_t *bytes;
} big_int_t;

void big_init(big_int_t *big, uint8_t size) {
  big->size = size;
  uint8_t bytes[size];
  big->bytes = bytes;
  uint8_t i;
  for(i=0;i<big->size;i++) big->bytes[i] = 0;
}

int main() {
  big_int_t a,b;
  big_init(&a,1);
  big_init(&b,1);
  a.bytes[0] = 16;
  b.bytes[0] = 41;
  printf("%d\n",a.bytes[0]);
  printf("%d\n",b.bytes[0]);
}

big_init 中,变量 bytes 是一个 local 变量,一旦函数 returns 就会超出范围并消失.存储在big->bytes中的指针在函数returns时会变成杂散指针,解引用指针会导致undefined behavior.

您不能为此使用本地数组,而是需要使用 malloc:

动态分配数组
big->bytes = malloc(sizeof(*big->bytes) * big->size);

但不要忘记 free 记忆完成后。

您正在堆栈上分配字节缓冲区:

uint8_t bytes[size];

当big_init退出时缓冲区不再有效。它会被随机覆盖。

您可能想使用 malloc() 动态分配它,但您必须小心再次释放它。

此行为的原因是您在 堆栈 上使用指针分配 bytes。第一次调用 big_init 时,局部变量 bytes 将被放入堆栈,它的地址将用于结构中的 bytes。之后,您将再次调用函数 big_init 。现在,与之前相同的堆栈被建立起来,局部变量bytes被放置在与之前相同的位置。因此,两次赋值导致同一个指针