常见内存错误:
结构体指针未初始化 ***结构体成员指针未分配足够的内存
内存分配成功但未初始化 ***
内存操作越界
动态内存申请之后,应该立即检查指针值是否为NULL,防止使用NULL指针:
int* p = (int*) malloc(56); if ( p != NULL) { //do something... } free(p);free指针之后必须立即赋值为NULL:
int* p = (int*) malloc(56); //do something... free(p); p = NULL; //do something... if( p != NULL) { //do something... }
任何与内存操作相关的函数都必须带长度信息:
void print(void* p, int size) { int i = 0; char buf[128] = {0}; snprintf(buf, sizeof(buf), "%s\n", "willwilling"); }malloc和free必须匹配,防止内存泄漏和多次释放。
#include <stdio.h> #include <malloc.h> void test(int* p, int size) { int i = 0; for(i=0; i<size; i++) { printf("%d\n", p[i]); } free(p); //应删除的代码 } void func(unsigned int size) { int* p = (int*)malloc(size * sizeof(int)); int i = 0; if( size % 2 != 0 ) { //reee(p); //应增加的代码 return; } for(i=0; i<size; i++) { p[i] = i; printf("%d\n", p[i]); } free(p); } int main() { int* p = (int*)malloc(5 * sizeof(int)); test(p, 5); free(p); func(9); func(10); return 0; }
free释放的是堆上的空间,如果对栈上的空间,会出现段错误。
原则:哪个函数申请就在哪个函数释放
内存泄漏对于服务器型程序是致命的错误。
小结:
内存错误的本质源于指针保存的地址为非法地址
指针变量未初始化,保存随机值
指针运算导致内存越界
内存泄漏源于malloc和free不匹配
当malloc次数多于free时,产生内存泄漏
当malloc次数少于free时,程序可能崩溃