局部变量-C++局部指针困惑,该程序为什么能正常输出

问题描述

C++局部指针困惑,该程序为什么能正常输出

int* pointBoom()//局部变量指针测试
{
int c = 20;
int *f = &c;//局部变量指针f
cout << "局部变量c的地址" << &c<<endl;
cout << "局部变量f存储的地址" << f<<endl;
cout << "局部变量f的地址" << &f<<endl;

return f;

}
int main()
{
cout << "调用函数pointBoom" << endl;
cout << "pointBoom的值是" << *pointBoom() << endl;
cout << "pointBoom中返回的地址是" << pointBoom() << endl;//第二次调用
return 0;
}

为什么程序正常,f指向的c是局部变量,c是在栈上分配的,函数调用结束后,不是销毁了么,f指向的内存地址中存储的变量不是为空么。为什么还能正常输出呢?

解决方案

这不难理解,对于绝大部分的实现(编译器)而言,他们是这样处理的:当函数调用时,总要遵循一种“调用约定”,对于大多数的调用约定而言,首先是参数入栈(可能有部分参数用寄存器传送),然后返回地址入栈(x86上就是把cs:eip入栈 ),CPU执行现场跳转,以C语言默认调用约定 __cdecl 为例,函数会用 push ebp 指令把ebp寄存器入栈,然后保存堆栈指针,即调用 mov ebp,esp 然后做一些工作,局部变量也在堆栈上面,然后就是函数里的代码了,就是你写的C/C++代码被编译器编译后的机器码,函数的最后三条指令通常是:mov esp,ebp ;pop ebp ;ret 。也就是说,函数只是简单的用ebp中存储的“栈顶指针”恢复到esp(x86CPU上用来存储栈顶指针的寄存器),这样就是平衡堆栈了。并没有把堆栈上的数据清零,所以在main函数里面,如果没有再使用这一部分堆栈(如调用其他函数)这时候的数据还是原来的。

解决方案二:

内存释放并不会对内存清零。它只是说该段内存可以被其它地方使用了。如果该段内存被其它使用并改写,你打印的值就变了。(野指针也是指针,只是说他指向的内容有可能被其它地方改变)。
指针指着一个生命周期结束的变量不仅可以访问,还可以修改,只不过这种访问是不确定的
局部变量的地址都是在程序自己的堆栈中,当局部变量结束后,只要没有将该局部变量的内存地址给别的变量,其值仍然存在。但如果修改的话,是比较危险的,因为这个内存地址可能给了程序的其它变量,通过指针强行修改的话,可能会引起程序崩溃

解决方案三:

栈上的内存通常是在程序开始时一次性分配的,所有一直都在,不会被释放。指向栈的指针几乎一定能用

解决方案四:

用我的理解说个通俗的比喻哈,不对的话请指正
这就好像你去开房(内存)的时候领了一把钥匙,你退房走人了没交钥匙(返回了指向局部变量的指针),但是房间还在,并不是你一退房房间也一起消失了
可是你之后再用这把钥匙访问的时候里面可能已经住了别人,你这种访问就是非常“不安全”的,所以要避免这种访问的发生
但你刚走,那个房间还没分给别人,这时你落在里面的手机还是在里面的,这就是为啥你这个程序还能正常输出

解决方案五:

内存有几种使用情况
1,被占用 通常函数调用会占用栈内存,变量定义会占用栈,静态区,内存
2,动态分配会占用 堆内存,你同时要用一个指针对象保存它,以便使用
3,代码一直占用代码区内存
所谓内存分配。一般是指
1)给某个名字(变量,数组等对象)安排一个位置,以便存取,这是系统自动分配的
2)动态分配内存,系统划拨一块没有名字的内存,程序一般用指针接收(直接简介和有名字的对象建立联系)
这是程序员手动写代码,分配的内存。

解决方案六:

用我的理解说个通俗的比喻哈,不对的话请指正
这就好像你去开房(内存)的时候领了一把钥匙,你退房走人了没交钥匙(返回了指向局部变量的指针),但是房间还在,并不是你一退房房间也一起消失了
可是你之后再用这把钥匙访问的时候里面可能已经住了别人,你这种访问就是非常“不安全”的,所以要避免这种访问的发生
但你刚走,那个房间还没分给别人,这时你落在里面的手机还是在里面的,这就是为啥你这个程序还能正常输出

解决方案七:

用我的理解说个通俗的比喻哈,不对的话请指正
这就好像你去开房(内存)的时候领了一把钥匙,你退房走人了没交钥匙(返回了指向局部变量的指针),但是房间还在,并不是你一退房房间也一起消失了
可是你之后再用这把钥匙访问的时候里面可能已经住了别人,你这种访问就是非常“不安全”的,所以要避免这种访问的发生
但你刚走,那个房间还没分给别人,这时你落在里面的手机还是在里面的,这就是为啥你这个程序还能正常输出

解决方案八:

用我的理解说个通俗的比喻哈,不对的话请指正
这就好像你去开房(内存)的时候领了一把钥匙,你退房走人了没交钥匙(返回了指向局部变量的指针),但是房间还在,并不是你一退房房间也一起消失了
可是你之后再用这把钥匙访问的时候里面可能已经住了别人,你这种访问就是非常“不安全”的,所以要避免这种访问的发生
但你刚走,那个房间还没分给别人,这时你落在里面的手机还是在里面的,这就是为啥你这个程序还能正常输出

解决方案九:

用我的理解说个通俗的比喻哈,不对的话请指正
这就好像你去开房(内存)的时候领了一把钥匙,你退房走人了没交钥匙(返回了指向局部变量的指针),但是房间还在,并不是你一退房房间也一起消失了
可是你之后再用这把钥匙访问的时候里面可能已经住了别人,你这种访问就是非常“不安全”的,所以要避免这种访问的发生
但你刚走,那个房间还没分给别人,这时你落在里面的手机还是在里面的,这就是为啥你这个程序还能正常输出

解决方案十:

用我的理解说个通俗的比喻哈,不对的话请指正
这就好像你去开房(内存)的时候领了一把钥匙,你退房走人了没交钥匙(返回了指向局部变量的指针),但是房间还在,并不是你一退房房间也一起消失了
可是你之后再用这把钥匙访问的时候里面可能已经住了别人,你这种访问就是非常“不安全”的,所以要避免这种访问的发生
但你刚走,那个房间还没分给别人,这时你落在里面的手机还是在里面的,这就是为啥你这个程序还能正常输出

时间: 2024-10-31 06:29:13

局部变量-C++局部指针困惑,该程序为什么能正常输出的相关文章

声明-返回局部指针,typedef struct {}*p问题

问题描述 返回局部指针,typedef struct {}*p问题 #include #define ElemType char //节点声明,数据域.左孩子指针.右孩子指针 typedef struct BiTNode{ char data; struct BiTNode *lchild,*rchild; }BiTNode,*BiTree; //先序建立二叉树 BiTree CreateBiTree(){ char ch; BiTree T; scanf("%c",&ch);

dll里面初始化结构体,返回应用程序指向结构体的指针,应用程序可以通过这个指针读取它的成员变量吗

问题描述 dll里面初始化结构体,返回应用程序指向结构体的指针,应用程序可以通过这个指针读取它的成员变量吗 dll里面初始化结构体,返回应用程序指向结构体的指针,应用程序可以直接通过这个指针读取它的成员变量吗? 解决方案 当然是可以的.但是更好的方式是把分配内存的工作交给调用者去做.因为这样不容易忘记释放内存.申请和释放的代码成对出现. 参考windows api里的GetWindowRect,它由调用者传入一个lpRect结构体指针,函数获取了窗口坐标,填充它. 解决方案二: 只要是在同一个

关于数组指针的c++程序,不知道为什么错了

问题描述 关于数组指针的c++程序,不知道为什么错了 #include #include using namespace std; int main(){ char str1[80], str2[80]; char pc1 = str1, *pc2 = str2; cin >> pc1 >> pc2; char a[80][80]; for (unsigned i = 0; i<strlen(str1) - strlen(str2) + 1; i++){ for (unsig

c++-编写一个C++程序,有个输出最长的符合要求的字母。

问题描述 编写一个C++程序,有个输出最长的符合要求的字母. 编写程序: 如果一个字母延伸到中线之上,如d或f,则称其有上出头部分(ascender). 如果一个字母延伸到中线之下,如p或g,则称其有下出头部分(dexcender). 编写程序,读入一个单词文件,输出最长的即不包含上出头部分,也不包含 下出头部分的单词. 解决方案 用动态规划 和查找最长公共子串的算法类似,先构造后缀数组,然后排序,遍历,找到最长的.

msi-用vs2010 打包程序的时候 主输出创建不了快捷方式

问题描述 用vs2010 打包程序的时候 主输出创建不了快捷方式 如题 如图 为什么创建不了快捷方式 我是用 vs2010 开发的QT 程序我参考了 网上的文档 但是不知道为什么 这里创建不了快捷方式 当我帮生成的.exe文件 放进去后 可以创建快捷方式而主输出不可以 还有 打包的 时候如果我不像生成 msi 文件 而只生成一个 exe文件的话我该怎么操作啊 解决方案 那个是复制粘贴的,修改一下名称

windows应用程序中获取控制台输出信息

问题描述 我在一个C#Windows应用程序中启动一个控制台程序,这个控制台程序输了很多信息我怎么才能在C#windows应用程序中获得这些信息 解决方案 解决方案二:是不是什么重定向??学习解决方案三:专业接分,参考http://blog.csdn.net/jinjazz/archive/2008/05/07/2413039.aspx解决方案四:引用2楼jinjazz的回复: 专业接分,参考http://blog.csdn.net/jinjazz/archive/2008/05/07/2413

编写程序,生成并输出杨辉三角形(10行)。

问题描述 编写程序,生成并输出杨辉三角形(10行). 在C语言中,运用数组,编写程序,生成并输出杨辉三角形(10行). 解决方案 http://blog.sina.com.cn/s/blog_49fb2853010004lt.html 解决方案二: 杨辉三角形的第n行的第m个元素等于n!/((n-m)!*m!) 因此编程如下 int x = 10; for (int n = 1; n < x; n++) { for (int m = 1; m <= n; m++) printf("%

string-为什么赋给值指针(动态指针)值时,两次输出不一样?并且输出的地址也不一样,怎么让它们一样

问题描述 为什么赋给值指针(动态指针)值时,两次输出不一样?并且输出的地址也不一样,怎么让它们一样 #include #include using namespace std;main(){ string str1; cout<<""输入一个数""; cin>>str1; char *Num1=new char[str1.length()]; int *num1=new int[str1.length()]; str1.copy(Num1st

请大神指导-用 if ......else 语句 写的程序结果为什么会输出两次?以下是源代码:

问题描述 用 if ......else 语句 写的程序结果为什么会输出两次?以下是源代码: import java.util.Scanner; public class Work0225_8 { public static void main(String[] args) { // 输入三个double型的数据,放入到abc三个变量中去 // 使用条件结构与交换逻辑将这三个变量中的值从小到大排列. System.out.println(""请您输入第一个double型数据 :&quo