认识指针
内存
作用域 | 生命周期 | |
---|---|---|
全局内存 | 整个文件 | 应用程序的生命周期 |
静态内存 | 声明它的函数内部 | 应用程序的生命周期 |
局部内存 | 声明它的函数内部 | 限制在函数执行时间内 |
动态内存 | 由引用改内存的指针决定 | 直到内存被释放 |
常量与指针
指针类型 | 指针是否可修改 | 指针指向的数据是否可修改 |
---|---|---|
指向非常量的指针 | 是 | 是 |
指向常量的指针 | 是 | 否 |
指向非常量的常量指针 | 否 | 是 |
指向非常量的非常量指针 | 否 | 否 |
堆和栈
堆 | 栈 | |
---|---|---|
申请方式 | 调用malloc、alloc获取 | 当用户定义临时变量就会产生 |
释放 | 使用free()进行释放,否则就会出现内存泄漏问题 | 当前代码域退出时自动释放 |
生命周期 | 随整个程序的,只有当该程序退出时,才由系统进行释放,否则会一直存在 | 在申请点的作用域退出时自动释放 |
大小 | 堆的空间一般比较大 | 栈空间相对小 |
C的动态内存管理
内存泄漏
如果不再使用已分配的内存却没有将其释放就会发生内存泄露,导致内存泄漏的情况如下:
- 丢失内存地址
- 应调用free函数却没有调用(隐式泄漏)
动态内存分配函数
函数 | 描述 |
---|---|
malloc | 从堆上分配 |
realloc | 在之前分配的内存块的基础上,将内存重新分配为更大或者更小的部分 |
calloc | 从堆上分配内存并清零 |
free | 将内存返回堆 |
迷途指针
内存已经被释放但是指针还在引用原始内存,这样的指针被称为迷途指针。迷途指针没有指向有效对象有时候也称为过早释放。
使用迷途指针会造成一系列问题,包括:
- 如果访问内存,则行为不可预期
- 如果内存不可访问,则是段错误
- 潜在的安全隐患
导致这几类问题的情况可能如下:
- 访问已释放内存
- 返回的指针指向的是上次函数调用中的自动变量
处理迷途指针
- 释放指针后置位NULL
- 写一个特殊的函数替代free函数
- 有些系统会在释放后复写数据,如果程序员在预期之外的地方看到这些值,可以认为程序可能在访问已释放的内存
- 用第三方工具检测