为什么将C字符串传入函数的C/C++示例程序无法输出预期结果?
问题根因:类型不匹配导致的未定义行为
你碰到的问题核心是数组指针和二级指针是完全不兼容的类型,强制转换只是骗过了编译器,本质上还是非法内存访问。
1. 先明确两个变量的类型差异
- 栈数组
char str[30]的取地址结果&str类型是char (*)[30],即「指向长度为30的char数组的指针」,它的数值和数组首元素地址&str[0]一致,但类型完全不同。 - 动态分配的指针
char* strNew的取地址结果&strNew类型才是char**,即「指向char指针的指针」,它的数值是strNew这个指针变量本身在栈上的内存地址,该地址里存储的是new申请的堆内存首地址。
2. 二级指针解引用的行为差异
函数内的strcpy(*strOut, "Hello Tommy")会先对传入的二级指针解引用,拿到目标内存地址再做拷贝:
- 传入合法的
&strNew时:*strOut得到的就是strNew里存储的堆内存首地址,往这个地址写内容完全合法,所以能正常输出。 - 传入强制转换的
&str时:*strOut会把str数组的前sizeof(char*)个字节的内容当成目标地址(比如64位系统下就是前8个字节),而栈上的str数组未初始化,这8个字节是随机垃圾值,相当于你往一个随机的非法内存地址写字符串,直接触发未定义行为,轻则程序崩溃无输出,重则篡改其他内存数据。
3. 正确写法参考
如果要操作栈数组,根本不需要传二级指针,直接传一级指针即可:
void fillMeUp( char* strOut ) { strcpy( strOut, "Hello Tommy" ); } int main() { char str[30]; fillMeUp(str); // 数组会隐式退化为首元素指针,无需强制转换 printf("%s\n", str); }
另外你用的C风格强制转换会主动屏蔽类型错误,如果换成C++的static_cast<char**>(&str),编译器会直接报错,提示类型不兼容,从根源上避免这类问题。
内容的提问来源于stack exchange,提问作者user16929596
相关产品推荐
相关产品推荐

