C语言栈相关,指针操作以及局部变量函数返回的相关问题

#include
void test2(int *l){
printf("l:%p,*l:%d\r\n",l,*l);
int mm[10]={1,2,3,4,5,6,7,8,9,10};
printf("mm:%p,l:%p,*l:%d\r\n",mm,l,*l);

int m=*l;
printf("m:%d\r\n",m);

}
void test(int a){
int b = 5;
*a = &b;
printf("a:%p,*a:%p,
a:%d\r\n",a,*a,**a);
}
int main(void){
int ptr2 = NULL;
test(&ptr2);

int mm[10]={1,2,3,4,5,6,7,8,9,0};

printf("m:%p,*m:%p,
*m:%d\r\n",&ptr2,ptr2,*ptr2);
test2(ptr2);
printf("m:%p,*m:%p,**m:%d\r\n",&ptr2,ptr2,*ptr2);
return 0;
}
问题1:test2函数中mm数组的元素个数少于10个的时候, printf("m:%d\r\n",m);的结果m是5
当超过10个元素的时候,printf("m:%d\r\n",m);的结果m是10,这是为什么?
问题2:这里边在test函数中b变量是局部变量,在test函数结束后局部变量b应该从栈中弹出了,为什么在test2中还可以访问到?推测原因是因为弹栈只是将栈顶指针移动了,b的地址上的值并没有清空,不知道这么想对不对?

1个回答

你这样胡乱提问我也很无奈。你的代码都没有贴对,所以天知道你的代码是什么,假设是如下的代码

#include<stdio.h>

void test2(int *l){
printf("l:%p,*l:%d\r\n",l,*l);
int mm[10]={1,2,3,4,5,6,7,8,9,10};
printf("mm:%p,l:%p,*l:%d\r\n",mm,l,*l);
int m=*l;
printf("m:%d\r\n",m);
}
void test(int** a){
int b = 5;
*a = &b;
printf("a:%p,*a:%p,a:%d\r\n",a,*a,**a);
}
int main(void){
int * ptr2 = NULL;
test(&ptr2);

int mm[10]={1,2,3,4,5,6,7,8,9,0};

printf("m:%p,*m:%p,*m:%d\r\n",&ptr2,ptr2,*ptr2);
test2(ptr2);
printf("m:%p,*m:%p,**m:%d\r\n",&ptr2,ptr2,*ptr2);
return 0;
} 

如果不是,那么你自己对照。

问题1:这个应该是编译器相关的,在我这里,元素11的时候,还是输出5
问题2:你说的对,除非新的数据放入堆栈,堆栈当然不会被清空

图片说明

weixin_42135997
猿猿_yzg ok,了解了,十分感谢
一年多之前 回复
caozhy
贵阳老马马善福专业维修游泳池堵漏防水工程 可以这么理解。其实计算机里,删除不清零是惯例。比如你删除硬盘的文件,也是只清文件表项而已,所以删除了还能找回来。堆内存释放也是如此。数据库也是如此。几乎都是如此。
一年多之前 回复
weixin_42135997
猿猿_yzg 回复caozhy: 好像有一点明白了,你看我理解的对不对,就是说,在函数test结束后,栈顶指针恢复到原来的位置,而栈顶指针的位置是不变化的,所以在再次调用的时候,入栈又是从这个位置开始进栈的,导致入栈的数据累加到这个地址的时候就会覆盖掉test2中未手动清空掉的数据,这样理解对不对?
一年多之前 回复
weixin_42135997
猿猿_yzg 好像有一点明白了,你看我理解的对不对,就是说,在函数test结束后,栈顶指针恢复到原来的位置,而栈顶指针的位置是不变化的,所以在再次调用的时候,入栈又是从这个位置开始进栈的,导致入栈的数据累加到这个地址的时候就会覆盖掉test2中未手动清空掉的数据,这样理解对不对?
一年多之前 回复
caozhy
贵阳老马马善福专业维修游泳池堵漏防水工程 回复weixin_42135997: 那当然了,因为一个是参数,一个是局部变量,都在堆栈上。你要在mm前面加上一些别的局部变量,这个值就会改变。
一年多之前 回复
weixin_42135997
猿猿_yzg 代码是跟你整理出来的是一样的,然后关于问题一,你这个调试结果可以看出来在数组个数是10个的时候,test2函数中的m值是一个随机值,然后从地址值上看,数组个数不论是多少,l的地址值减去mm数组的首地址的值都是固定的大小,我使用gcc编译器这个地址差值始终是36(十进制数),这是为什么,麻烦大神帮忙解答一下
一年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐