在结构中初始化数组
Initializing arrays in struct
所以我决定用 C 为微控制器(如果重要的话是 PIC32)编写我自己的大整数库,但我遇到了一个我不明白的奇怪问题。当代码为 运行 时,big_int_t
结构 a
和 b
位于不同的内存位置,但 a->bytes
和 b->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
被放置在与之前相同的位置。因此,两次赋值导致同一个指针。
所以我决定用 C 为微控制器(如果重要的话是 PIC32)编写我自己的大整数库,但我遇到了一个我不明白的奇怪问题。当代码为 运行 时,big_int_t
结构 a
和 b
位于不同的内存位置,但 a->bytes
和 b->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
被放置在与之前相同的位置。因此,两次赋值导致同一个指针。