为何函数参数为char*时修改字符串未触发段错误?
问题:为何修改char*类型的函数参数未触发段错误?
我们知道char str[] = "Gear";声明的字符数组可以被修改,而char* str = "Gear";指向的是字符串字面量,属于只读内存,修改会触发段错误。但下面这段程序中,PrintStr函数的参数是char* str,修改str[0]为'D'却没有触发段错误,反而正常打印出了字符串:
void PrintStr(char* str) { str[0] = 'D'; puts(str); } int main() { char str[] = "Gear"; PrintStr(str); return 0; }
为何将函数参数声明为char* str没有产生预期的段错误?我原本预期修改时会触发段错误。
解答
核心原因是你混淆了char*指针指向的两种不同内存区域:
- 主函数里的
char str[] = "Gear";是在栈上分配了一块可写内存,并把字符串字面量"Gear"的内容拷贝到了这块栈内存里。这个数组本身是完全可修改的。 - 当调用
PrintStr(str)时,传递给函数参数char* str的是栈上这个可写数组的首地址。此时函数里的str指针指向的是栈上的可写内存,不是只读的字符串字面量。 - 所以修改
str[0] = 'D'本质是修改栈上的可写内存,完全合法,自然不会触发段错误。
你之前的预期错误,是误以为只要函数参数是char*,就一定指向只读的字符串字面量,但实际上char*只是一个通用的字符指针,它可以指向任何字符类型的内存——不管是只读的字面量,还是可写的栈/堆内存,全看它实际接收的地址是什么。
内容的提问来源于stack exchange,提问作者Vishal
相关产品推荐
相关产品推荐

