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

未分配内存的二维指针**assign为何能正常输出与**c相同的数据?

为什么未分配内存的二维指针**assign能获取**c的值?

我为二维指针**c分配内存、初始化并赋值,希望**assign获取**c的值。但我仅声明了二维指针**assign,未分配内存,代码却能成功运行并输出与**c相同的结果,请问这是为什么?

示例代码

int main(){ 
    int i,j; 
    float **c=NULL, **assign=NULL; 
    c = (float **)calloc(2,sizeof(float *)); 
    for (i=0;i<2;i++){ 
        c[i] = (float *)calloc(3,sizeof(float)); 
    } 
    for (i=0;i<2;i++){ 
        for (j=0;j<3;j++){ 
            c[i][j] = i+j; 
            printf("c[%d][%d]=%f\n",i,j,c[i][j]); 
        } 
    } 
    assign = c; 
    for (i=0;i<2;i++){ 
        for (j=0;j<3;j++){ 
            printf("assign[%d][%d]=%f\n",i,j,assign[i][j]); 
        } 
    } 
    return 0; 
}

问题解析

这个问题的核心其实是指针的本质——存储内存地址的变量,咱们一步步拆解:

  • 首先,**c是一个二维指针,你通过calloc给它分配了两层内存:

    • 第一层:c = (float **)calloc(2,sizeof(float *)) —— 这是一块能存2个float*地址的内存,c本身就指向这块内存的起始地址。
    • 第二层:循环里给每个c[i]分配了3个float的内存,所以c[i]指向对应那行浮点数数组的起始地址。
  • 当你执行assign = c;的时候,根本不是把c指向的所有数据复制给assign,而是把c这个指针变量里存储的内存地址,直接赋值给了assign。

  • 这时候,assign和c就变成了「指向同一块内存区域的两个指针」—— 你没有给assign分配新的内存,但是assign现在和c盯着同一个地方。所以当你用assign[i][j]访问的时候,本质上还是在访问c之前分配的那堆内存里的数据,自然输出结果和c一样。

举个生活化的例子:你有一把钥匙(c),能打开一个放了两抽屉文件的柜子(c分配的内存)。现在你复制了一把一模一样的钥匙(assign = c),这把新钥匙(assign)没配新柜子,但它能打开同一个柜子,所以你用新钥匙拿出来的文件,和原来那把钥匙拿的完全一样。

⚠️ 注意:如果之后你用free释放了c指向的内存,那assign也会变成野指针,再访问assign[i][j]就会触发未定义行为,因为它指向的内存已经被系统回收了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:04:31