未分配内存的二维指针**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
相关产品推荐
相关产品推荐

