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

C语言传递数组/指针时如何让函数修改不影响main原数组

实现方案

你当前的示例代码属于C标准定义的未定义行为:将const限定的数组地址隐式转换为非const指针后修改,不同编译器、编译选项下的运行结果不可控——可能出现修改同步到原数组的情况,也可能直接触发运行时崩溃。

要实现「main内数组不可直接修改、传参给其他函数后修改不影响原数组、无需手动拷贝数组」的需求,有两种成熟实现方式:


方案1:结构体包装数组 + 值传递(跨平台通用,无依赖)

C语言语法不支持数组直接按值传参,但结构体默认按值传递。把数组包装在结构体内部,给main中的结构体实例加const修饰即可满足全部要求:

  • main内受const限定,直接修改数组内容会触发编译报错,无法直接修改
  • 传参时编译器会自动生成结构体(含内部数组)的完整副本传递给被调函数,被调函数的所有修改都作用在副本上,不会影响原数组
  • 拷贝动作由编译器自动完成,不需要手动编写memcpy或循环拷贝的逻辑,全平台兼容。

实现代码:

#include <stdio.h>

// 用结构体包装目标数组
typedef struct {
    int arr[4];
} IntArray;

void fun(IntArray arr_copy);

int main()
{
    const IntArray a = {.arr = {1,2,10,20}};
    // a.arr[3] = 42;  // 取消注释会直接编译报错,main内无法修改
    fun(a); // 值传递,编译器自动拷贝数组
    printf("main中a.arr[3] = %d\n", a.arr[3]); // 固定输出20,原值不受影响
    return 0;
}

void fun(IntArray arr_copy)
{
    arr_copy.arr[3] = 42; // 仅修改自动生成的副本
    printf("fun内部arr_copy.arr[3] = %d\n", arr_copy.arr[3]); // 输出42
}

运行输出:

fun内部arr_copy.arr[3] = 42
main中a.arr[3] = 20

这个方案是最通用的实现,适合绝大多数常规场景。


方案2:操作系统级写时复制(COW,适合超大数组场景)

如果数组体量极大,每次传参全量拷贝会带来明显的性能开销,可以借助操作系统的内存管理特性实现写时复制:将原数组所在内存页标记为只读私有映射,初始状态下不会拷贝任何内存数据,只有当被调函数尝试写入数组内存时,操作系统才会自动复制被写入的内存页供修改使用,原数组所在内存页完全不会被改动。
这个方案同样不需要手动拷贝数组,且只有实际发生写入时才会复制对应内存页,大数组场景下性能远高于全量拷贝,但缺点是依赖操作系统的内存API,跨平台兼容性差。以下是Linux环境下的参考实现:

#include <stdio.h>
#include <sys/mman.h>
#include <unistd.h>
#include <string.h>

void fun(int *arr) {
    arr[3] = 42;
    printf("fun内部a[3] = %d\n", arr[3]); // 输出42
}

int main() {
    long page_size = sysconf(_SC_PAGESIZE);
    // 分配页对齐的私有匿名内存映射
    int *a = mmap(NULL, page_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    // 初始化数组内容
    memcpy(a, (int[]){1,2,10,20}, sizeof(int)*4);
    // 将内存页设置为只读,触发写时复制机制
    mprotect(a, page_size, PROT_READ);
    // main内直接执行a[3] = 42会触发SIGSEGV段错误,满足只读要求
    fun(a);
    printf("main中a[3] = %d\n", a[3]); // 固定输出20
    munmap(a, page_size);
    return 0;
}

不建议继续使用最初的写法:通过强转const指针修改const限定的内存,属于未定义行为,代码的运行结果没有任何保障。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 14:09:15