C / C++

char数组的字符串是存在哪里的,是常量区还是栈区?

如char n[]="123" char数组的字符串是存在哪里的,是常量区还是栈区,我查了很多资料,有些说在栈区,有些说在常量区,只是在常量区拷贝了一…
关注者
29
被浏览
15,546

3 个回答

虽然从常量区拷贝到栈上面肯定没错,但是搞两份拷贝有点浪费,毕竟这个字符串只用在初始化这个局部变量了。所以具体还是看编译器了。

我测试了一下。对于程序:

void foo() { char n[] = "This is a string"; }

如果用 64 位的 WSL 下用 GCC 编译,这个字符串本身是硬编码在指令里面的。图:

注意第 0x17 和 0x25 字节开始的那两条指令的立即数,其实就是 "Thing is a string" 的 ASCII 码:


而对于微软的 CL,

这段代码确实是把字符串存在常量区,然后运行的时候拷贝的:

另外 clang 好像也是写在常量区然后拷贝。就不贴那么多图片了。

编辑于 2018-04-01 21:02

肯定是有两份的。

理由很简单:

因为你现在可以修改这个char数组了。

修改常量区内容?怎么想都不太对吧。


好吧其实我推出结果的过程是不严谨哒,我错了……但我觉得这种细究下去太没意思了。


栈虽然不是堆那样动态的,但也是运行时才确定的,栈上的数据没法凭空出现,总得有个源头(除非是一些立即数,被编码到指令里了)。

char[4],其实编码进指令也不是不可以,毕竟也就一个int的大小……但是我想不出编译器这么做的理由——写编译器的人难道就喜欢加班吗……


有一种可能是n就在常量区,没有拷贝。但你可以修改这个数组了,所以显然很矛盾,不const了。

所以就只剩下需要拷贝这么一种可能了。两个地方~~


GCC居然优化到指令里了!可怕……

编辑于 2018-04-02 00:43

看你怎么初始化的了,如果用“123”的方式初始化就是在常量区

如果用{'1','2','3'}这种方式初始化就是在栈区

编辑于 2018-04-02 21:25
( 为什么?)