|
1、返回局部变量的地址,或者返回指向局部变量的指针 { int val; return &val; } 2、引用已经被释放了的堆内存(野指针) int * heapref(int n, int m){ int i; int *x, *y; x = (int *)malloc(n * sizeof(int)); /* 各种操作 */ free(x); x = NULL; y = (int *)malloc(m * sizeof(int)); for(i = 0; i < m; i++) { y = x++; // 此处的x之前已经被释放了! } } 3、内存泄漏 malloc和free没有配套使用 void leak(int n){ int *x = (int *)malloc(n * sizeof(int)); return; } 或者: char *p = (char *)malloc(10);p = (char *)malloc(10); 结构体资源释放常见内存泄漏问题 struct a{ int buf_size; char *buf; }; struct a *p = (struct *a)malloc(sizeof(struct a));
free(p->buf); 多步骤内存初始化 char *buf1; char *buf2; int module_init() { buf1 = (char *)malloc(100); if(buf1 == NULL) return -1; buf2 = (char *)malloc(100); if(buf2 == NULL) return -1;//执行到这里,buf1内存泄漏 free(buf2); free(buf1); ... } 解决对策是对出错处理修改成goto语句,而非直接return。 调用了会分配内存的函数,使用完未做内存回收处理。 实际开发最常见,常常是调用会分配内存的第三方函数库。 char *func ( ){ return (char *)malloc(20); // make sure to memset this location to ‘\0’… } void callingFunc ( ) { char * p = func ( ); // Problem lies here ... } 4、栈越界 {char buf[5]; sprintf(buf, "%s", "hello world"); } 上面的代码导致栈缓冲区溢出,安全的做法是: 1)根据需求定义合适的buffer; 2)采用snprintf(buf, sizeof(buf), "%s", "hello world")来及时截断。 5、误认为从堆分配的内存被初始化为0 int *p = malloc(24 * sizeof(int));char a[] = “abcdefghiafa”; int i = 0; while(a != '\0') { i++; p[*a - 'a']++; } 6、引用未初始化的指针,或者访问NULL指针 int *p;int a = *p; 7、间接访问无效地址,类似于引用未初始化的指针 如从stdin读取一个int变量时,scanf("%d", &val);是正确用法,若误写为scanf("%d", val);时,val的值会被解释为一个地址,并试图向该地址写数据。在最好的情况下,进程立即异常中止。在最坏的情况下,val的值恰好对应于虚拟存储器的某个合法的具有读/写权限的内存区域,于是该内存单元会被改写,而这通常会在相当长的一段时间后造成灾难性的、令人困惑的后果。 8、堆越界 char *p = (char *)malloc(10);char *q = (char *)malloc(10); char a[20] = "abcdefghijklmno" memcpy(p,a,sizeof(a));//可能无意中修改了q指针指向的堆数据 9、谨慎使用strcpy,memcpy等拷贝函数,字符串数组赋值之前或者定义之后最好memset一下 char p[10];strcpy(p,"hello world!");//数组越界 strncpy(p,"hello world!",sizeof(p));//不越界,但是少了结尾'\0' memset(p,'\0',sizeof(p)); strncpy(p,"hello world!",sizeof(p) - 1);//正确 10、使用未初始化的内存 char *p = (char *)malloc(10);char a[10] = "abcd"; strcpy(a,p);//结果未知 11、当使用malloc来申请内存时,应该用if(p != NULL)进行防错检查。 12、意图通过传递指针来分配内存 void *GetMemory(void *p,int n){ p = malloc(n); return p; } char *p; GetMemory((void *)p,10); *p = 'a'; |
微信公众号
手机版