指针+程序运行的内存管理

指针

一个类型的指针包含三个信息:地址、 步长、内容如何解析

C中的野指针,C++中的迷途指针(失控指针或悬浮指针)都是不为NULL的指针,也不是指向常量的指针,而是指向“垃圾”内存的指针。“垃圾”的意思是未知区域、未知内存。

指针——就是一个地址,空指针——NULL,野指针——未初始化的指针,void指针(空类型指针)——void *p
注意:(1)空类型指针可以指向任何类型的数据,包含他们的地址。
(2)任何指针都可以赋值给空类型的指针,用于保存地址。

一个指向整型数的指针  int*p
一个指向整型数指针的指针  int **p
一个有10个整型指针的数组  int *p[10]
一个指向有10个整型数数组的指针  int (*p)[10]
一个指向函数的指针,该函数有一个整型参数,并返回一个整型数 int ( *p)(int)
一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数,并返回一个整型数。  int(*p[10])(int)
一个指向函数指针的指针,所指向的函数有一个整型参数,并返回一个整型数。 int (**p)(int)

在函数调用的时候
用1级指针形参,去间接修改了0级指针(实参)的值。
用2级指针形参,去间接修改了1级指针(实参)的值。
用3级指针形参,去间接修改了2级指针(实参)的值。
用n级指针形参,去间接修改了n-1级指针(实参)的值。


程序运行的内存载入过程:

memset函数

从数组str的首地址开始,前进 5个字节,进行赋值,赋值一个字符 ’ A ’ 。
  memset(str, ’A’ ,5) ;  

对20个字节全部赋值为0,对于数组清零 (num是数组)
   memset(num, 0 ,20);

(1)程序要进行的操作对应的代码被装载到代码区。
(2)全局和静态数据等装载到数据区
(3)开辟堆栈,供临变量等使用。

内存分配:

1)静态存储区:主要存放static静态变量、全局变量、常量。这些数据内存在编译的时候就已经为他们分配好了内存,生命周期是整个程序从运行到结束。
(2)栈区:存放局部变量。在执行函数的时候(包括main这样的函数),函数内的局部变量的存储单元会在栈上创建,函数执行完自动释放,生命周期是从该函数的开始执行到结束。(例如,delay_ms(){ int a = 1000;//a就是一个局部变量 在栈区建立存储单元 delay_ms()执行完毕后自动释放 })
(3)堆区:程序员自己申请一块任意大小的内存—也叫动态内存分配。这块内存会一直存在知道程序员释放掉。C语言中,用malloc or new动态地申请内存,用free or delete释放内存。良好习惯:若申请的动态内存不再使用,要及时释放掉,否则会造成内存泄露


记住规则:

【规则1】用malloc 或new 申请内存之后,应该立即检查指针值是否为NULL。防止使用指针值为NULL 的内存。
【规则2】不要忘记为数组和动态内存赋初值。防止将未被初始化的内存作为右值使用。
【规则3】避免数组或指针的下标越界,特别要当心发生“多1”或者“少1”操作。
【规则4】动态内存的申请与释放必须配对,防止内存泄漏。
【规则5】用free 或delete 释放了内存之后,立即将指针设置为NULL,防止产生“野指针”。


系统响应:

对于堆,应知道系统有一个记录空闲内存地址的链表,当系统收到程序申请时,遍历该链表,寻找第一个空间大于申请空间的堆结点,删除空闲结点链表中的该结点,并将该结点空间分配给程序(大多数系统会在这块内存空间首地址记录本次分配的大小,这样delete才能正确释放本内存空间,另外系统会将多余的部分重新放入空闲链表中)。
对于栈,只要栈的剩余空间大于所申请空间,系统为程序提供内存,否则报异常提示栈溢出。

空间大小:

堆是不连续的内存区域(因为系统是用链表来存储空闲内存地址,自然不是连续的),堆大小受限于计算机系统中有效的虚拟内存(32bit系统理论上是4G),所以堆的空间比较灵活,比较大。
栈是一块连续的内存区域,大小是操作系统预定好的,windows下栈大小是2M(也有是1M,在编译时确定,VC中可设置)。

碎片问题:

对于堆,频繁的new/delete会造成大量碎片,使程序效率降低。
对于栈,它是一个先进后出的队列,进出一一对应,不会产生碎片。
生长方向:
堆向上,向高地址方向增长。
栈向下,向低地址方向增长。

分配方式:

堆都是动态分配(没有静态分配的堆)。
栈有静态分配和动态分配,静态分配由编译器完成(如局部变量分配),动态分配由alloca函数分配,但栈的动态分配的资源由编译器进行释放,无需程序员实现。

分配效率:

堆由C/C++函数库提供,机制很复杂。所以堆的效率比栈低很多。
栈是极其系统提供的数据结构,计算机在底层对栈提供支持,分配专门寄存器存放栈地址,栈操作有专门指令
在栈区开辟一段内存,系统会自己回收。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值