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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:22:20