为什么未初始化的指针会指向一个不确定地址
2017-10-12 16:48
302 查看
分配一个变量是编译器还是系统的工作?
分配一个新变量的时候,编译器/系统为什么不会把该内存区域的数据清零为什么未初始化的指针/变量会指向一个随机值(不确定值),而不是NULL
为什么delete、free不会将使用的内存清零,然后再释放、把指针置NULL
内存中残留的数据还有意义吗?这点会被黑客利用吗?
为了效率,所以编译器/系统不做这些不必要的操作?
作者:明月楼高
链接:https://www.zhihu.com/question/40197087/answer/85434085
1、全局变量中的指针默认指向0,栈中的指针默认指向0xcccccccc,堆中的指针默认指向0xcdcdcdcd。对于在windows下的c语言写出的控制台程序和窗体程序,全局变量和局部static变量都是放在全局区域,这部分区域默认是0,至于为什么是0,我不知道。
2、栈中的指针,也就是在函数函数体内(包括main和其他的入口函数)声明的指针,默认值是0xcccccccc,在看汇编的时候可以发现,在函数调用过程中,参数入栈,调整栈帧后,编译器会生成一段额外的代码用来初始化调用栈,也就是把这些地方的数据全部改为0xcccccccc(0xcc的汇编语言是int3,中止的意思,相当于插入断点)。
3、堆区的数据默认是0xcd(堆区可以分配的地方默认是0xcd,关于堆我了解的不多,有误请指出),但是在堆中的指针我还没有见过,int*p=new int这种方法定义的指针p在栈中,它ta指向堆中的一个地方。
4、delete和free只是把堆中的这块区域标记为空闲。标记空闲只需要把该区域加入到堆的空闲链表中就可以了。如果要置0,效率会低。
5、内存中残留数据一般出现在堆中,这些数据应该很难被黑了利用吧,第一,这些数据在庞大的堆中,由于已经泄露,所以找到他们很难,其次,就算找到了这些数据的位置,但你不知道这些16进制数代表什么?字符?数字?还是其他。不过不排除一些黑客真的去找到了这些数据然后进行分析。比如你把你的银行卡密码存了起来然后只是简单的把ta delete掉, int* key=new int,*key=123456,delete key,这样的话123456还在堆中,还是可以找到的(就像大海捞针,只是不太容易
相关文章推荐
- C/C++ 指向字符的指针为什么可以用字符串来初始化,而不是字符地址。
- 改变指针指向的地址为什么需要二维指针,从汇编角度分析
- 用一个指向int的指针来存储一个对象的地址。
- 用一个指向int的指针来存储一个对象的地址。
- 不能通过键盘输入一个字符串,并使未初始化的指针指向它
- 我有一个char * 型指针正巧指向一些int 型变量, 我想跳过它们。为什么如下的代码((int *)p)++; 不行?
- 知道指针地址 , 怎么取出指针指向的内容??? 0x7fff5fbff564 这种值 怎么赋值给一个变量??
- 【c语言】编写一个函数new,对n个字符开辟连续的存储空间,此函数应返回一个指针(地址),指向字符串开始的空间
- 习题 8.19(1) 编写一个函数new,对n个字符开辟连续的存储空间,此函数应返回一个指针(地址),指向字符串开始的空间。new(n)表示分配n个字节的内存空间。
- 假设以带头结点的循环链表表示队列, 并且只设一个指针指向队尾元素结点(注意不设头指针) 试编写相应的队列初始化,入队列和出队列的算法
- C++中不同指针指向同一个字符串,然而地址相同
- 编写一个函数new,对n个字符开辟连续的存储空间,此函数应返回一个指针(地址),指向字符串开始的空间。new(n)表示分配n个字节的内存空间。
- 对于一颗完全二叉树,要求给所有节点加上一个pNext指针,指向同一层的相邻节点;如果当前节点已经是该层的最后一个节点,则将pNext指针指向NULL;给出程序实现,并分析时间复杂度和空间复杂度。
- /* 用指向指针的指针的方法对n个整数排序并输出 。要求将排序单独写成一个函数。n个整数在主函数中输入,最后在主函数中输出*/
- 如何初始化一个指针数组
- 为什么基类指针可以指向派生类对象,而派生类则不可以指向基类
- 采用new运算符创建一个指向二维数组的指针的两种方式
- 在一个无头指针的单链表中,删除指针p所指向的结点
- 基于外部一个省市联动js框架,实现初始化特定的地址级联
- 链表添加函数中为什么要用指向链表指针的指针