C语言传递指针后,指针指向的值未改变的问题咨询
为什么你的C语言指针参数没修改原变量?
嗨,我来帮你搞明白这个问题~ 你遇到的核心问题其实是C语言里参数传递的本质,再加上代码里的几个小坑,咱们一步步拆解:
核心原因:C是按值传递的,哪怕传指针也一样
你可能以为传指针就能修改外面的变量,但其实在C里,不管你传的是什么类型,函数拿到的都是参数的副本。
比如你在main里调用changeFileName(sourceFileName),这里传递的是sourceFileName这个指针变量的副本——也就是它当前指向"sample"的地址。在changeFileName函数里,你修改的是这个副本的指向(让它指向temp),但原变量sourceFileName的指向根本没被碰过!函数结束后,副本被销毁,原变量自然还是原来的样子。
你的代码里还有两个隐藏坑
除了值传递的问题,你的代码里还有两个容易踩的雷:
- 缓冲区溢出:你定义的
char temp[] = "";长度只有1(只存了字符串结束符\0),但strcpy(temp, new_name)要把长度为9的"new_name"(加上\0)塞进去,这会直接越界写内存,属于未定义行为,运气差的话程序会崩溃。 - 野指针风险:
temp是函数内部的局部数组,函数执行完后,这块内存会被系统回收。就算你能把这个地址传回main,后续访问它也会是野指针,结果不可预测。
两种修正方案
根据你的需求,有两种常见的解决办法:
方案1:传递指针的指针(修改指针的指向)
如果你就是想让原指针指向新的字符串,那需要传递指针的地址(也就是char **类型),这样就能在函数里修改原指针的指向了。注意要使用动态内存分配(比如malloc),避免局部变量的内存被回收:
#include <string.h> #include <stdio.h> #include <stdlib.h> void changeFileName(char **fileName) { // 分配足够存"new_name"的内存(加1是给结束符留位置) char *new_name = malloc(strlen("new_name") + 1); if (new_name == NULL) { perror("malloc failed"); return; } strcpy(new_name, "new_name"); printf("... function: changeFileName, BEFORE: fileName = <%s>\n", *fileName); *fileName = new_name; // 这里修改的是原指针的指向 printf("... function: changeFileName, AFTER : fileName = <%s>\n", *fileName); } int main () { char *sourceFileName = "sample"; printf("\nfunction: main, BEFORE: fileName = <%s>\n\n", sourceFileName); changeFileName(&sourceFileName); // 传递指针的地址 printf("\nfunction: main, AFTER : fileName = <%s>\n\n", sourceFileName); free(sourceFileName); // 记得释放动态分配的内存 return 0; }
方案2:修改字符串内容(而非指针指向)
如果你只是想修改原字符串的内容,那要确保原指针指向的是可修改的内存(比如栈上的数组,而不是只读的字符串常量),然后直接修改内容,同时注意缓冲区大小避免溢出:
#include <string.h> #include <stdio.h> void changeFileName(char *fileName, size_t maxLen) { const char new_name[] = "new_name"; printf("... function: changeFileName, BEFORE: fileName = <%s>\n", fileName); // 用strncpy确保不会溢出,最后手动加结束符 strncpy(fileName, new_name, maxLen - 1); fileName[maxLen - 1] = '\0'; printf("... function: changeFileName, AFTER : fileName = <%s>\n", fileName); } int main () { char sourceFileName[20] = "sample"; // 用数组存,不是只读的字符串常量 printf("\nfunction: main, BEFORE: fileName = <%s>\n\n", sourceFileName); changeFileName(sourceFileName, sizeof(sourceFileName)); // 同时传缓冲区大小 printf("\nfunction: main, AFTER : fileName = <%s>\n\n", sourceFileName); return 0; }
最后再划个重点
- C语言的参数传递永远是值传递,要修改外面的变量(包括指针),必须传它的地址。
"sample"这种字符串常量是只读的,不能直接修改内容,要修改的话得用数组或者动态分配的内存。- 函数内部的局部变量内存会被回收,不要让外部指针指向它,否则会出现野指针问题。
内容的提问来源于stack exchange,提问作者Bauerhof
相关产品推荐
相关产品推荐

