关于字符串的内存地址

本文通过两段C语言代码实例,详细分析了不同情况下返回字符串内容的行为差异。一种情况是返回局部数组的地址,导致输出乱码;另一种情况是返回字符串字面量的地址,则能正常打印。文章深入探讨了栈空间、常量区及它们对程序运行的影响。
看到一篇博客,给出了下面一道关于C内存的笔试题:
char*getmemory(void)
{
char p[]="hello world";
return p;
}
void test(void)
{
char *str=null;
str=getmemory();
printf(str);
}
请运行test()函数,会有什么样的结果?
看完第一反应是输出"hello world"。但是,看了博主的解析,发现给出的答案是,输出乱码。
博主的分析详见:
从他的角度分析的很好。
如果题目中将字符串改成是字符数组,我也会选择输出乱码,但是如果是字符串,就有些纠结了。
但是他在分析的时候都是以局部变量地址来讨论的,假设"hello world"位于栈中。
由于char p[]="hello world";是定义了一个字符数组,并使用"hello world"初始化其内容,sizeof(p)是12字节,p是栈中。
所以返回的时候,p的空间被释放了,返回的指针指向的地址已经无效。所以输出为乱码。
 
但是,如果修改为char *p="hello world";则会正常打印"hello world"。原因如下:
这里定义了一个指针p,p指向"hello world"的首地址。由于字符串在C中相当于常量,而常量是在rodata段,并不在栈中。这个地址是一直存在的。这也是为什么指向字符串的指针,无法修改其内容一样。
即:
char*getmemory(void)
{
char *p="hello world";
p[0] = 'h';
return p;
}
会发生段错误提示。
 
以下是测试:
从四次打印输出来看,地址是一致的。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值