数组中的相同字符串具有相同的内存地址

时间:2014-10-17 21:17:22

标签: c++ arrays memory string-literals

为什么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:   ""

1 个答案:

答案 0 :(得分:4)

它被称为常量合并。通常,它在更高的优化级别启用。编译器只需获取所有唯一的常量值并将其压缩。有利于内存使用和缓存效率。

gcc有-fmerge-constants或使用-O和公司

其他编译器可能会也可能不会这样做。它是特定于编译器的。

由于它是关于最容易实现的优化操作,我想象所有C ++编译器都会这样做。

这是一个很好的例子:

  1. 您不能对常量值的存在位置做出假设(未定义的行为)
  2. 您不应该对常量值(未定义的行为)进行更改
  3. 但我们看到很多关于人(不是你自己)的问题,观察他们在抛弃const之后修改了一个常量字符串。