静态存储区和动态存储区
内存主要分为两类,静态存储区和动态存储区
静态存储区
分为只读数据(READONLY DATA)区、以读写数据(RW DATA)区、未初始化区(BSS) 。
它们都是在程序编译连接阶段确定的,在程序执行的阶段不会改变。
用于存储全局变量、静态变量(全局和局部静态变量)、字符串常量(无名的静态变量),这些变量的空间在程序编译时就已经分配好了。
动态存储区
分为堆(heap)和栈(stack)
都是程序执行的过程中动态分配的,大小也随之动态变化。从内存管理的实现的角度看来,堆使用的链表实现的,而栈使用的是线性存储的方法。
局部变量和函数参数的存储单元存储在栈中,函数运行结束时,这些内存区域会自动释放
new、malloc、calloc、realloc申请的内存在堆中,需要手动free,否则它就一直存在,直到程序结束;
C语言必须注意的几个问题:
- 内存泄露:申请一块内存,但没有释放,程序结束也没回收,导致其他程序不能使用
- 野指针:指一个内存指针已经被释放free或者realloc,但指针依然在使用。避免野指针的情况,将内存的指针置为NULL,并在程序使用的时候判断该内存是否为NULL,如为空,则认为该内存已经释放,不对内存进行访问。
- 非法释放内存:原则上讲只有被malloc(),calloc()或realloc()分配并通过返回值返回返回的内存才能被释放,否则释放除此以外的内存都是非法的。即使有一个指针是*p是malloc,那么对p1=p++,这个时候free(p1)也是不合法的,但free§确实可以的。同样释放函数中的局部变量也是非法的。还有一种情况是,对一个堆内存释放两次也是错误的用法。因为free()函数是 不能释放未分配的堆内存。在程序使用free释放内存之后,应该将指针置为NULL,free个NULL地址是没有问题的。