【发布时间】:2012-09-12 18:03:41
【问题描述】:
当我在我的 Linux x86_64 机器上编译并运行以下由 GCC 编译的 C 程序时:
#include <stdio.h>
int main(void)
{
char *p1 = "hello"; // Pointers to strings
char *p2 = "hello"; // Pointers to strings
if (p1 == p2) { // They are equal
printf("equal %p %p\n", p1, p2); // equal 0x40064c 0x40064c
// This is always the output on my machine
}
else {
printf("NotEqual %p %p\n", p1, p2);
}
}
我总是得到如下输出:
等于 0x40064c 0x40064c
我知道字符串存储在一个常量表中,但与动态分配的内存相比,地址太低了。
与以下程序比较:
#include <stdio.h>
int main(void)
{
char p1[] = "hello"; // char arrar
char p2[] = "hello"; // char array
if (p1 == p2) {
printf("equal %p %p\n", p1, p2);
}
else { // Never equal
printf("NotEqual %p %p\n", p1, p2); // NotEqual 0x7fff4b25f720 0x7fff4b25f710
// Different pointers every time
// Pointer values too large
}
}
这两个指针不相等,因为它们是两个可以独立操作的数组。
我想知道 GCC 是如何为这两个程序生成代码的,以及它们在执行过程中是如何映射到内存的。由于这已经被记录了很多次,因此也欢迎任何指向文档的链接。
【问题讨论】:
-
你总是可以在拆卸时达到顶峰。这是一个很好的技能,你需要在未来再做一次。
-
您的示例代码中只有两个字符串:
equal %p %p\n和NotEqual %p %p\n。p1和p2只是初始化为某个值的字符数组变量,然后将其用作字符串。特别是,您仍然可以使用p1[0] = 'H'; p2[0] = 'J';,例如,没有任何问题。如果您希望p1和p2成为字符串常量,请使用static const char p1[] = "Hello";。至少 GCC-4.6.3 将本地 const 数组视为变量,而不是真正的只读常量,因此需要static。而且它不会合并字符串,因此两者具有不同的指针。你用的是哪个编译器?
标签: c linux string gcc compiler-construction