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

C语言传&str3给char* string[]形参为何能访问其他相邻字符串

C语言指针传参越界访问现象解析

示例代码与运行结果

测试代码如下:

#include <string.h> 
#include <stdio.h> 
#include <stdlib.h>

void fn(char *string[]) {  
    printf("string[0] - %p %s\n", string[0], string[0]);
    printf("string[1] - %p %s\n", string[1], string[1]);
    printf("string[2] - %p %s\n", string[2], string[2]);
    printf("string[3] - %p %s\n", string[3], string[3]);
}

int main(int argc, char *argv[]) {
   char *str1 = "AAAAA";
   char *str2 = "XXXXX";
   char *str3 = (char*)malloc(sizeof(char) * strlen(str1) + 1);
   strcpy(str3, "BBBBB"); 
   char *str4 = "CCCCC"; 

   fn(&str3);

   return 0;
}

运行输出:

string[0] - 0x561c977682a0 BBBBB
string[1] - 0x561c96884050 AAAAA
string[2] - 0x561c96884056 XXXXX
string[3] - 0x561c9688405c CCCCC

核心疑问

调用fn函数时仅传入了实参&str3,fn的形参定义为char *string[]。已知malloc分配的空间位于动态内存区(堆),str3指向该堆内存区域,而str1、str2、str4为指向字符串常量的指针,在内存中按地址递增顺序连续存放(str1<str2<str4)。为何仅传入str3的地址,fn函数却能依次访问到str1、str2、str4指向的字符串内容?&str3实参与char* string[]形参之间的内存关联逻辑是什么?

原理解释

  • 函数形参的自动退化规则
    C语言标准明确规定:当数组类型作为函数形参时,会被编译器自动调整为指向数组首元素类型的指针。因此形参写char *string[],和写char **string完全等价,fn函数本质只接收一个二级指针(指向char*类型变量的地址),并不会真的开辟一个指针数组的空间。
  • 局部变量的栈存储布局
    main函数中定义的str1、str2、str3、str4都是char*类型的局部变量,全部被分配在main函数的栈帧上。在当前的编译环境、编译选项下,这几个指针变量在栈上是连续存放的:str3变量的存储地址之后(向高地址方向),依次排列着str1、str2、str4三个指针变量的存储空间,每个空间都存着对应字符串常量/堆内存的首地址。
  • 越界访问的实际逻辑
    当传入&str3时,形参string的值就是栈上str3变量的地址:
    • 访问string[0]等价于*(string + 0),即从str3的存储位置取出存的地址值,也就是堆上"BBBBB"的首地址,属于合法访问,结果符合预期。
    • 访问string[1]等价于*(string + 1),C语言指针运算会自动按指向类型的大小偏移:string是char**类型,偏移1单位的步长是一个char*的长度(64位系统下通常为8字节),刚好跳过str3的存储空间,读到栈上相邻位置存的str1的值,也就是"AAAAA"的首地址。
    • 同理string[2]、string[3]会继续向后偏移8字节,依次读到str2、str4存储的地址值,最终打印出对应的字符串。

注意:这是典型的未定义行为,不属于C语言的标准特性。栈上局部变量的排布顺序受编译器版本、优化等级、栈保护机制、目标平台架构影响极大,调整任意编译参数、调换变量定义顺序甚至增加无关代码,都可能导致访问结果错乱,甚至触发段错误,生产环境绝对不能编写这类越界访问内存的代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 16:18:24