⛵三、常见的动态内存错误
1)对空指针NULL的解引用操作
2)对动态开辟空间的越界访问
当I = 10时越界访问
3)对非动态开辟内存使用 free 释放
free一定是释放堆区上的数据
4)对同一块动态内存的多次释放
5)使用 free 释放一块动态开辟内存的一部分
free要指向开辟好空间的起始位置,防止开辟空间指针的自增自减运算
6)动态开辟内存忘记释放(导致内存泄露)
(没停止运行我电脑死机了!!!……)
忘记释放不再使用的动态开辟的空间会造成内存泄漏。
✨四、经典笔试题练习
题目1:
✨请问运行Test函数会有什么样的结果?
✨
程序崩溃,无法打印
分析:
改进方法一:
改进方法二:
题目2:
✨请问运行Test函数会有什么样的结果?
✨
str非法访问,程序出错,出现返回栈空间地址的问题
退出函数时被销毁了,虽然返回了但是在栈区退出时被销毁了,重新赋予p随机值
分析:
习题3:
✨请问运行Test函数会有什么样的结果?
✨ 没有释放动态开辟的内存(free),导致内存泄漏
习题4:
✨请问运行Test函数会有什么样的结果?
✨ 提前释放内存,后面strcpy函数非法访问
⏲五、C/C++程序的内存开辟
C/C++程序内存分配的几个区域:
栈区(stack)
:在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些 存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有 限。 栈区主要存放运行函数而分配的局部变量、函数参数、返回数据、返回地址等。堆区(heap)
:一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。分配方式类似于链表。数据段(静态区)(static)
:存放全局变量、静态数据。程序结束后由系统释放。代码段
:存放函数体(类成员函数和全局函数)的二进制代码。
有了这幅图,我们就可以更好的理解在《C语言初识》中讲的static关键字修饰局部变量的例子了。
实际上普通的局部变量是在栈区分配空间的,
栈区的特点是在上面创建的变量出了作用域就销毁。
但是被static修饰的变量存放在数据段(静态区),数据段的特点是在上面创建的变量,直到程序结束才销毁 所以生命周期变长。