C中的静态常量字符*与常量字符*
C中的C中的静态常量字符*与常量字符*,c,memory,static,string-literals,C,Memory,Static,String Literals,C中的const char*和static const char*有什么区别 我认为这个问题的答案是错误的 实际上,const char*元素被放入程序的.rodata部分,否则以下情况将导致segfault: const char* f() { const char* hello = "hello"; return hello; } int main() { const char* hello_after = f(); printf("%s\n", hello
const char*
和static const char*
有什么区别
我认为这个问题的答案是错误的
实际上,const char*
元素被放入程序的.rodata
部分,否则以下情况将导致segfault:
const char* f() {
const char* hello = "hello";
return hello;
}
int main() {
const char* hello_after = f();
printf("%s\n", hello_after);
}
实际上,由于该代码可以工作,因此f
返回的指针仍然指向活动数据,这表明该数据没有分配到堆栈上,而是存储在.rodata
中
但是在我看来,constchar*
和staticconstchar*
对于GCC来说是一样的
但是,为什么常量int*
和静态常量int*
的行为不一样呢?在GCC中硬编码的例外情况是,只有类型char
的const
和static const
应该相同吗
非常感谢你的帮助 在此函数声明中
const char* f() {
const char* hello = "hello";
return hello;
}
指针hello指向具有静态存储持续时间的字符串文字“hello”。也就是说,具有静态存储持续时间的不是指针,而是具有静态存储持续时间的指针文本。在函数的每次调用中,指针都会重新初始化
如果将函数声明为
const char* f( ) {
static const char* hello = "hello";
return hello;
}
在这种情况下,指针本身具有静态存储持续时间。它在程序获得控件之前初始化一次,并且在函数调用之间保留其值
例如,考虑这个演示程序。
#include <stdio.h>
const char* f( int i )
{
static const char* hello = "hello";
if ( i == 1 ) hello = "bye";
else if ( i == -1 ) hello = "hello";
return hello;
}
int main(void)
{
puts( f( 0 ) );
puts( f( 1 ) );
puts( f( 0 ) );
return 0;
}
也就是说,最初指针hello是由字符串文本“hello”初始化的
那么由于这个电话,
puts( f( 1 ) );
它的价值被改变了。现在它指向字符串文字“bye”
第三个电话呢
puts( f( 0 ) );
指针保留上次调用函数时分配给它的值
这是由于指针具有静态存储持续时间的事实。这与
常量字符*
关系不大,而与字符串文字(“hello”
在本例中)关系更大。我认为您误解了链接的答案。他们讨论指针的存储位置,而不是字符串文本。指针的存储方式将因使用static
而有所不同。如果使用-fsanitize=address
编译,则会出现运行时错误()引号:“实际上,const char*元素放在程序的.rodata部分…”错误-字符串文字不是指针。谢谢,我理解您的答案!所以我想这里的独特之处在于,我们处理的是字符串文本?如果相反,我们有const int hello[5]={1,2,3,4,5}.rodata
中。在该示例中,您有一个数组对象,而不是指针对象,这会改变一些情况。一个实现可以做任何能给出正确结果的事情,但是请注意,如果函数是递归输入的,那么必须有两个地址不同的hello
数组。好的!我现在不知道C对数组的处理与指针不同。@CosmoSterin这个{1,2,3,4,5}不是“数组文字”。这是用于初始化数组元素的初始值设定项。这与您将在块范围char s[]=“hello”中写入的内容相同;用于初始化数组的字符串文字的字符。但是,如果在没有存储说明符static的情况下声明数组,则该数组本身不具有静态存储持续时间。
puts( f( 0 ) );