我已经编程C了一段时间(但对C来说还是很新)我有时会对C处理内存的方式感到困惑。
请考虑以下有效的C片段:
const char *string(void)
{
/* where is this pointer variable located in the memory? */
const char *s;
/* where is this text data located in the memory? */
/* and when the program allocates memory for it? */
s = "Hello, World";
return s;
}
int main(void)
{
printf( "%s", string() );
return 0;
}
我在问内存究竟发生了什么? 指针变量's'不是局部变量,或者指针变量存储在内存中的位置。另外文本常量“Hello,World”存储在内存中(这不是被认为是函数返回后无法访问的局部变量)?
基本上哪种变量/数据被认为是在函数的“本地”范围内(在函数返回后仍然可以访问)?
我希望你能理解我想说的话:D ..我想我有很多关于编译器和可执行文件的知识,所以请随意启发我!
答案 0 :(得分:4)
我在问内存到底发生了什么?
正在堆栈上分配局部变量。 常量(包括文字字符串)正在可执行文件的文本或数据部分中分配。
指针变量's'不是局部变量吗?
是
或指针变量存储在内存中的哪个位置?
本地 s
位于寄存器或堆栈中。
还有哪些文本常量“Hello,World”存储在内存中?
在.text或.data部分中。它是常量,但遗留代码有时会修改它们,因此它取决于编译器选项。您需要区分引用和对象才能理解它。
(这不是被认为是函数返回后无法访问的局部变量)?
好吧,s
是本地的,但每次调用函数时都需要字符串本身,并且在发生这种情况之前本地帧甚至不会存在,所以常量本身很可能存储在。文字部分。它可以存储在.data中,具体取决于编译器选项以及当前编译器版本关于编译遗留代码的程度。表达式中的文字与分配给它的变量完全不同。
基本上哪种变量/数据被认为是在函数的“本地”范围内(在函数返回后不再可访问)?
词法范围为auto
变量的那些变量,即在没有static
存储类的函数内声明。遗憾的是,accessible
这个词有点不精确。对于静态存储类,如果对象的地址泄露出函数,则可以引用该对象。
答案 1 :(得分:2)
编译器已经准备好了字符串"Hello, World"
的存储,以便在加载应用程序时它具有自己的内存地址。
然后,当您的代码s = "Hello, World";
运行时,您将已编译字符串的内存地址复制到指针s
。没有为字符串分配额外的内存,s
本身是临时占用堆栈空间的局部变量(指针)。
答案 2 :(得分:1)
s = "Hello, World";
s
是一个局部变量,而"Hello World"
是一个字符串文字存储在内存的const区域,并具有静态存储持续时间。函数返回时s
被销毁,但字符串文字"Hello World"
没有。
答案 3 :(得分:1)
s
在堆栈中,并在string()
返回时不再存在。文字字符串存储在程序的只读数据中(这可能是也可能不是程序代码的一部分,具体取决于编译器和操作系统);使用gcc
,您可以通过编译-fwritable-strings
使其成为读写初始化数据的一部分,但这是一个坏主意(它主要是为希望字符串文字可写的古代程序提供的)。
答案 4 :(得分:0)
试试这个。可以工作
#include static char* str1(void){ static char* s="abc"; return s; } int main(int argc,char* argv[]){ printf("%s\n",str1()); return 0; }
'const'是'不应该是左值'。 变量的'static'是'静态分配'。 (你要返回一个静态字符串)
varible s指向“静态分配”的区域