将 malloc 与静态指针一起使用

Using malloc with static pointers

我知道声明一个 ststic 变量并以这种方式初始化它static int *st_ptr = malloc(sizeof(int)); 会产生一个编译错误消息(Type initializer element is not constant),并通过这种方式使用单独的语句来解决这个问题static int *st_ptr; st_ptr = malloc(5*sizeof(int));


我需要了解在这种情况下初始化运算符和赋值运算符之间的区别?以及为什么这样可以解决问题?

粗略地说,C中的初始化就是编译器输出二进制数据到可执行文件;赋值是由实际可执行代码执行的操作。

所以,static int i = 5使编译器输出数据字5到可执行文件的数据段;而 int i = func() 使编译器生成多个 CPU 指令作为 call 调用子程序和 mov 存储结果。

因此表达式 static int i = func() 需要 1) 比 main() 更早计算(因为这是一个初始化),2) 一段要执行的用户代码(这可能只有意义在新程序实例的上下文中)。可以通过创建一些在 main() 之前执行的隐藏初始化子例程来解决该问题。实际上,C++ 就是这样做的。但是C没有这个特性,所以静态变量只能用常量初始化。

当一个变量在函数内被声明为静态时,它是在 "data segment" 或 "bss segment" 中创建的,这取决于它是否被初始化。
这个变量是在二进制文件中创建并且必须有一个常量值 - 记住 - 函数内的静态变量是在程序运行时甚至在 main() 启动之前创建的,它不能用任何函数初始化,因为程序没有 'run' yet(没有任何类型的评估或函数调用)
因此初始化程序必须是常量或不首先初始化。

static int *st_ptr = malloc(sizeof(int));

在这里,您将 st_ptr 的创建与 malloc 绑定在一起,但是由于 malloc 是一个需要 运行 的函数,并且必须在任何其他函数 [=30 之前创建 st_ptr =]s - 这会造成不可能的状态

static int *st_ptr;
 st_ptr = malloc(5*sizeof(int));

此处,st_ptr 已创建并未初始化,它的创建未绑定到任何函数。 每次函数 运行s - malloc 发生。所以 malloc 的激活和创建 st_ptr 是不依赖的。

但正如我在评论中所述 - 这是极其危险的做法。您在同一个变量上分配越来越多的内存。避免它的唯一方法是 free(st_ptr) 在每个函数的末尾。这就是说 - 你不需要它首先是静态的

首先,让我们简要介绍一下 initializationassignment

  • 初始化:

这用于指定对象的初始值。通常,这意味着只有在定义变量时,才会进行初始化。初始化对象的 value 称为 initalizer。来自 C11 ,章节 6.7.9

An initializer specifies the initial value stored in an object.

  • 赋值:

赋值是在任何(有效的)给定执行时间点分配(或设置)变量的值。引用标准,章节6.5.16

An assignment operator stores a value in the object designated by the left operand.

如果是简单赋值(=运算符),

In simple assignment (=), the value of the right operand is converted to the type of the assignment expression and replaces the value stored in the object designated by the left operand.


也就是说,我认为您的查询与 static 对象的初始化有关。

对于第一种情况,

static int *st_ptr = malloc(sizeof(int)); 

引用自 C11 标准文档,第 §6.7.9 章,初始化,第 4 段,

All the expressions in an initializer for an object that has static or thread storage duration shall be constant expressions or string literals.

关于常量表达式,来自同一文档的第 6.6 章,(强调我的)

Constant expressions shall not contain assignment, increment, decrement, function-call, or comma operators, except when they are contained within a subexpression that is not evaluated.

显然,malloc(sizeof(int)); 不是 常量表达式,因此我们不能用它来初始化 static 对象。

对于第二种情况,

static int *st_ptr;
st_ptr = malloc(5*sizeof(int));

您没有初始化 static 对象。你离开它未初始化。下一条指令,您要将 分配 malloc() 的 return 值给它。所以你的编译器不会产生任何抱怨。