1 野指针 野猫 野狗 野孩子 熊孩子 NULL地址-狗链子
野孩子:没人要,没人管的孩子;行为动作不守规矩,调皮捣蛋的孩子。
野狗:没有主人的狗,没有链子锁着的狗,喜欢四处咬人。
对付野孩子的最好办法是给他定一套规矩,好好管教。一旦发现没有按规矩办事就好.
好收拾他。对付野狗最好的办法就是拿条狗链锁着它,不让它四处乱跑.
对付也指针肯怕比对付野孩子或野狗更困难。
我们需要把对付野孩子和野狗的办法都用上。既需要规矩,也需要链子。前面我们把内存比作尺子,很轻松的理解了内存。
尺子上的 0 毫米处就是内存的 0 地址处,也就是 NULL 地址处。
这条栓“野指针”的链子就是这个“NULL”。
定义指针变量的同时最好初始化为 NULL,用完指针之后也将指针变量的值设置为 NULL。
也就是说除了在使用时,别的时间都把指针“栓”到 0 地址处。
这样它就老实了。
2 栈、堆和静态区
一层教学楼,可能有外语教室,允许外语系学生和老师进入;
还可能有数学教师,允许数学系学生和老师进入;
还可能有校长办公室,允许校长进入。
同样,内存也是这样,内存的三个部分,不是所有的东西都能存进去的。静态区:保存自动全局变量和 static 变量(包括 static 全局和局部变量)。静态区的内容在总个程序的生命周期内都存在,由编译器在编译的时候分配。
栈:保存局部变量。 栈上的内容只在函数的范围内存在,当函数运行结束,这些内容也会自动被销毁。其特点是效率高,但空间大小有限。
堆:由 malloc 系列函数或 new 操作符分配的内存。其生命周期由 free 或 delete 决定。在没有释放之前一直存在,直到程序结束。其特点是使用灵活,空间比较大,但容易出错。
3 常见内存错误
指针没有指向一块合法的内存
定义了指针变量,但是没有为指针分配内存,即指针没有指向一块合法的内存。
1. 结构体成员指针未初始化
#include <cstring>
#include <stdlib.h>
#include <iostream>
struct student
{char *name;int score;
}stu,*pstu;int main()
{// 还没有为结构体分配内存//std::strcpy(stu.name,"Jimy");// 内存访问出错// stu.score = 99;struct student* pst = (struct student*)malloc(sizeof(struct student));pst->name = (char*)malloc(sizeof(char));// 这个好像不加上也可以,看编译器===std::strcpy(pst->name,"Jimy"); pst->score = 99;std::cout << pst->name << std::endl;free(pst);return 0;
}
函数 入口 的 指针变量检测 使用 assert(NULL != p)对参数进行校验
字符串拷贝 strlen(p1) 获取的长度 不包括结束符
char *p1 = “abcdefg”;
// char *p2 = (char *)malloc(sizeof(char)*strlen(p1));// 未包括结束符
char* p2 = (char*)malloc(sizeof(char)*(strlen(p1)+1));//
// 不要因为 char 类型大小为 1 个 byte 就省略 sizof(char)这种写法。这样只会使你的代码可移植性下降.
strcpy(p2,p1);
memset 初始化内存
int a[10];
memset(a,0,sizeof(a));
// memset 函数有三个参数,
// 第一个是要被设置的内存起始地址;
// 第二个参数是要被设置的值;
// 第三个参数是要被设置的内存大小,单位为 byte。
内存越界
这种错误经常是由于操作数组或指针时出现“多 1”或“少 1”。比如:
int a[10] = {0};
for (i=0; i<=10; i++) // for (i=0; i<10; i++) 左闭右开写法=============
{a[i] = i;// 无 a[10]
}
内存泄漏 由malloc 系列函数或 new 操作符分配的内存。如果用完之后没有及时 free 或 delete,这块内存就无法释放,直到整个程序终止。
malloc 返回指针 NULL 申请0字节内存
申请 0 字节内存,函数并不返回 NULL,而是返回一个正常的内存地址。
但是你却无法使用这块大小为 0 的内存。
这好尺子上的某个刻度,刻度本身并没有长度,只有某两个刻度一起才能量出长度。
对于这一点一定要小心,因为这时候 if(NULL ! = p)语句校验将不起作用。
malloc 与 free 配对使用 一定要一夫一妻制,不然肯定出错。
malloc 两次只 free 一次会内存泄漏; malloc 一次 free 两次肯定会出错。
也就是说,在程序中 malloc 的使用次数一定要和 free 相等,否则必有错误。
这种错误主要发生在循环使用malloc 函数时,往往把 malloc 和 free 次数弄错了。
释放完块内存之后,没有把指针置 NULL,这个指针就成为了“野指针”,也有书叫“悬垂指针”。
这是很危险的,而且也是经常出错的地方。所以一定要记住一条: free 完之后,一定要给指针置 NULL。
参考
https://github.com/Ewenwan/ShiYanLou