You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言字符串字面量数组存储机制及代码中wp指针指向问题解析

问题:C语言中字符串字面量数组是如何存储的?

先直接点出你代码里的核心问题:第一个循环的逻辑完全错误,导致指针越界访问了不属于你的字符串字面量的内存区域,这就是你看到奇怪输出的原因。下面一步步拆解细节:

1. 第一个循环的错误分析

你的第一个循环代码是:

char *words[] = {"wehrmarcht", "collectorate", "hello", "hello","precorrection", "hello","wehrmarcht"};
char *wp;
// ...
for(wp = *words; wp - *words < sizeof(words); wp += strlen(wp) + 1) {
    printf("wp -> %s\n", wp);
}

这里有两个致命错误:

  • 错误1:错误假设字符串字面量是连续存储的
    words是一个char*类型的数组,每个元素都是指向独立字符串字面量的指针。这些字符串字面量在内存中不是连续排列的——编译器会把它们放在只读数据段的不同位置(就算是相同字面量被合并,依然不会和其他字符串连续)。你用wp += strlen(wp)+1试图跳到下一个字符串,这完全是错误的,因为下一个字符串的地址和当前字符串的末尾没有任何"连续"的关联。
  • 错误2:循环条件的逻辑完全不匹配
    sizeof(words)得到的是整个指针数组的字节大小(在64位系统下,7个char*就是56字节),而wp - *words是计算两个字符指针之间的字符个数(因为wp和*words都是指向char的指针)。拿字符个数和数组的字节大小做比较,完全没有意义,这导致循环会一直执行直到wp越界,访问到内存里的其他数据(比如后面的代码段、其他变量的内容),所以你才会看到precorrection之后的奇怪输出,甚至把printf的格式字符串%s和分隔线都打出来了。

2. 第二个循环为什么正确

第二个循环是遍历指针数组words的每个索引:

for(int i = 0; i < sizeof(words) / sizeof(char *); i++) {
    printf("words[%d] -> %s\n", i,words[i]);
}

这里sizeof(words)/sizeof(char*)计算出数组的元素个数(7),然后逐个取出words[i]——也就是每个指向字符串字面量的指针,自然能正确打印每个字符串。

3. 字符串字面量的实际存储规则

最后回到你的原始问题,字符串字面量在C中的存储规则:

  • 通常被编译器放在只读数据段(比如.rodata),所以不能修改(修改会导致未定义行为)。
  • 编译器通常会做字符串池优化:如果代码中有多个相同的字符串字面量,编译器只会存储一份,所以你的words[0]和words[6](都是"wehrmarcht")、words[2]/words[3]/words[5](都是"hello")的指针值其实是相同的(你可以用printf("%p", words[i])验证)。不过这是编译器的可选优化,不是C标准强制要求的。

内容的提问来源于stack exchange,提问作者rlongying

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 12:32:30