【发布时间】:2014-10-17 21:17:21
【问题描述】:
为什么 char* 数组中的相同字符串具有相同的地址?
这是因为编译器优化吗?
例子:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ARR_SIZE 7
int main(int argc, char** argv) {
size_t i = 0, j = 0;
char * myArr[ARR_SIZE] = {
"This is the first string",
"This is the second string",
"This is Engie",
"This is the third string",
"This is Engie",
"This is the fifth string",
"This is Engie"
};
for (i = 0; i < ARR_SIZE; ++i){
for (j = i + 1; j < ARR_SIZE; ++j){
if (memcmp((myArr + i), (myArr + j), sizeof(char*)) == 0){
fprintf(stdout, "%p, %p\n", *(myArr + i), *(myArr + j));
fprintf(stdout, "found it start index: %lu, search index: %lu\n", i, j);
}
}
}
return 0;
}
GDB:
(gdb) x/7w myArr
0x7fffffffdd10: U"\x4007a8"
0x7fffffffdd18: U"\x4007c1"
0x7fffffffdd20: U"\x4007db"
0x7fffffffdd28: U"\x4007e9"
0x7fffffffdd30: U"\x4007db"
0x7fffffffdd38: U"\x400802"
0x7fffffffdd40: U"\x4007db"
(gdb) x/7s *myArr
0x4007a8: "This is the first string"
0x4007c1: "This is the second string"
0x4007db: "This is Engie"
0x4007e9: "This is the third string"
0x400802: "This is the fifth string"
0x40081b: "%p, %p\n"
0x400823: ""
【问题讨论】:
-
我的猜测是确实是因为优化,这很可能不违反
as-if规则,所以他优化了无用的副本 -
语言标准明确允许这样做。
-
了解带引号的字符串是文字,它们本质上存储在方法的指令流附近。它们占用编译模块中的物理空间。它们也是(表面上)“恒定的”并且不应该改变,即使系统在物理上没有阻止修改。所以复制它们是没有意义的。
-
值得注意的是,这甚至发生在 Java 中,其中字符串文字是“内部”的,因此堆中仅存在每个唯一值的一个副本。 (但请注意,我说的是“文字”。)
标签: c++ arrays memory string-literals