如果一个C函数被调用两次,它会创建一个在函数中声明的变量两次吗?
我有一个用C写的函数,它由如下指针变量组成如果一个C函数被调用两次,它会创建一个在函数中声明的变量两次吗?,c,printf,dynamic-memory-allocation,stdio,C,Printf,Dynamic Memory Allocation,Stdio,我有一个用C写的函数,它由如下指针变量组成 #include<stdio.h> void print() { char *hello="hello world"; fprintf(stdout,"%s",hello); } void main() { print(); print(); } #包括 作废打印() { char*hello=“hello world”; fprintf(标准输出,“%s”,您好)
#include<stdio.h>
void print()
{
char *hello="hello world";
fprintf(stdout,"%s",hello);
}
void main()
{
print();
print();
}
#包括
作废打印()
{
char*hello=“hello world”;
fprintf(标准输出,“%s”,您好);
}
void main()
{
打印();
打印();
}
如果我调用print()函数两次,它会为hello变量分配两次内存吗
如果我调用print()函数两次,它会为hello变量分配两次内存吗
不,它是一个字符串文本,只分配一次
您可以通过检查地址来检查:
fprintf(stdout,"%p: %s\n", hello, hello);
样本输出:
0x563b972277c4: hello world
0x563b972277c4: hello world
如果我调用print()函数两次,它会为hello变量分配两次内存吗
对。但是,hello
是一个指针,在64位机器上占用8字节的堆栈空间。成本实际上是无法衡量的。此外,编译器根本不需要分配变量,因为您从未尝试获取其地址。编译器可以自由地将代码有效地转换为:
void print()
{
fprintf(stdout, "%s", "hello world");
}
这意味着hello
的声明在运行时不会导致任何内存分配。并非出于所有目的,将hello
作为局部变量是免费的
相反,在应用程序的数据段中,以零结尾的字符串文字“helloworld”只分配一次。编译器可以这样做,因为它知道C字符串文本是只读的,所以不允许修改它。此外,在运行时不执行动态内存分配。字符串文本的内存是静态分配的,其生存期是应用程序的生存期
因此,您的print
功能基本上是尽可能便宜的-它根本不执行任何实际分配。您可以将代码粘贴到以查看发生了什么。根据您的代码,这是生成的assebler:
print(): # @print()
mov rcx, qword ptr [rip + stdout]
mov edi, offset .L.str
mov esi, 11
mov edx, 1
jmp fwrite # TAILCALL
main: # @main
push rax
mov rcx, qword ptr [rip + stdout]
mov edi, offset .L.str
mov esi, 11
mov edx, 1
call fwrite
mov rcx, qword ptr [rip + stdout]
mov edi, offset .L.str
mov esi, 11
mov edx, 1
call fwrite
xor eax, eax
pop rcx
ret
.L.str:
.asciz "hello world"
重要的部分在最后:
.L.str:
.asciz "hello world"
“hello world”
仅在此处声明,就像一个全局变量一样,每次调用函数print
时都会使用它
就像你这样声明:
#包括
const char*hello=“hello world”;
作废打印()
{
fprintf(标准输出,“%s”,您好);
}
void main()
{
打印();
打印();
}
在本例中,编译器看到了优化并进行了优化。但是,我不能肯定这种情况会一直发生,因为它不能依赖于编译器
hello
变量这取决于hello变量的内存。您是指用于字符串数据(“hello world”)的内存,还是用于变量本身的内存(将存储该数据的地址)?我是指存储字符串所需的总空间,该空间很可能由实现定义。大多数现代系统将为(常量)字符串文字数据创建空间,并在编译时初始化该数据。但他们没有义务这样做。(我想)是的,会的。但我认为这取决于编译器。将变量声明为全局变量只会占用空间1对吗?@selstingeorge字符串是全局的。编译器并不愚蠢,他们知道在这里分配多个字符串是不必要的。