【发布时间】:2020-10-17 04:39:17
【问题描述】:
您好,我有一个调用 malloc 的测试代码如下:
#include <stdio.h>
#include <stdlib.h>
int *p;// = (int*)malloc(sizeof(int));
int main() {
//...
}
当然,当使用error: initializer element is not constant 编译时,这段代码会失败,我已经引用了这个问题:Malloc function (dynamic memory allocation) resulting in an error when it is used globally。他们说我们必须在函数中使用malloc()。但是,如果我将代码更改为:
#include <stdio.h>
#include <stdlib.h>
int *p;
static int inline test_inline(int *x) {
printf("in inline function \n");
x = (int*)malloc(sizeof(int));
return x;
}
test_inline(p);
int main(){
//...
}
正如inline函数的定义:“内联函数是那些定义很小的函数,在发生函数调用的地方被替换。函数替换完全是编译器的选择。”所以这意味着我们可以将上面示例中的内联函数 test_inline 替换为其中的代码,这意味着我们在 global 中调用了 malloc() ?问题一:inline 或malloc() 有错吗?
问题 2:在我给出的关于 malloc function dynamic 的链接中,有一个答案说“不仅是 malloc,你不能像你在这里调用的那样调用任何函数。你只能在那里将函数声明为全局或本地函数”但我看到我们仍然可以在全局和全局中调用函数,我们不仅可以初始化如下声明:
#include <stdio.h>
#include <stdlib.h>
int b;
b = 1;
int test() {
printf("hello");
}
test();
int main() {
//...
}
所以这意味着在全局中我们仍然可以声明、初始化和调用函数。但是当我们编译上面的代码时,它有一个警告 warning: data definition has no type or storage class 那么为什么我们有这个带有变量 b 的警告呢?我在这里看不到任何无关紧要的事情。通过test(); 行,我在main() 之外调用了一个函数,我知道这是没有意义的,因为我们从未运行test(),但我没有问题,仍然构建成功。所以回到关于malloc() 的问题1,我认为答案是“我们不能在全局中调用函数或不能初始化”,我认为这不是真的。有没有更合理的解释?
【问题讨论】:
-
malloc是运行时操作。全局数据在编译时初始化,因此 - 在编译时malloc没有意义。原因是编译器在创建可执行文件时会进行地址空间优化。全局数据往往存在于二进制文件的.rodata、.bss或.data部分,而动态分配的内存来自堆。此外,当请求动态内存时,实际上是内核返回保留的堆空间作为系统调用的结果——所以再一次在编译时这样做是没有意义的。 -
第二个 sn-p 编译纯属巧合。 C 编译器威胁
test();和b=1;作为声明/定义等同于int test();和int b=1;作为旧版 C。由于这些与代码中的其他声明兼容,因此不会导致错误。把test的类型改成void就可以看到了。 -
@EugeneSh。刚刚将其放入答案中!
标签: c function malloc global inline