C语言疑问:内容相同的不同字符串为何地址一致?
为什么内容相同的不同字符串指针用
==比较会生效? 哈哈,这个问题我碰到过好多次了!这其实是C编译器的一个经典优化——**字符串常量驻留(String Pooling)**在搞怪!
核心原因:编译器的内存优化
当你像这样定义字符串指针时:
char *str1 = "Hello World"; char *str3 = "Hello World";
这些用双引号包裹的内容属于字符串常量,编译时会被存到程序的只读数据段里。为了节省内存空间,编译器会做一个优化:扫描所有字符串常量,如果发现内容完全一致的,就只保留一份拷贝,让所有指向该内容的指针都指向同一个内存地址。
这就解释了为什么你打印str1和str3的地址会完全相同——它们本质上指向的是同一块内存里的同一个字符串常量,所以用==比较指针地址时自然会返回真。
注意区分两种字符串定义方式
这个优化只针对字符串常量指针,如果是用栈数组或者动态分配的方式创建字符串,情况就完全不同了:
// 栈上的数组,每个数组都是独立的内存空间 char str1[] = "Hello World"; char str3[] = "Hello World"; // 动态分配的内存,也是独立的块 char *str1 = malloc(12); strcpy(str1, "Hello World"); char *str3 = malloc(12); strcpy(str3, "Hello World");
上面这两种情况里,str1和str3的地址肯定不同,用==比较会直接失败,这时候就必须用strcmp()来比较字符串的实际内容。
额外补充:优化是可配置的
不同编译器对这个优化的支持略有不同,比如GCC可以通过编译选项-fno-merge-constants关闭字符串常量驻留,关闭后即使内容相同的字符串常量也会被存在不同的内存地址里,这时候用==比较就会返回假了。
总结
虽然这个编译器优化让你偶然用==比较成功了,但这只是特殊场景下的巧合!在任何需要比较字符串内容的业务场景中,一定要用strcmp()函数——==永远只会比较指针的地址,只有当两个指针指向同一块内存时才会相等,这不是我们想要的“内容相等”判断。
内容的提问来源于stack exchange,提问作者Drakalex
相关产品推荐
相关产品推荐

