1. 对空指针的解引用操作
int main()
{
int *p = malloc(INT_MAX);
*P = 20;
free(p);
return 0;
}
malloc开辟的空间足够大,并且没有对指针p进行合理的判断,那么p有可能是空指针,空指针解引用这种错误就在这种情况下很容易出现。
2.对动态开辟空间的越界访问
int main()
{
int *p =(int *) malloc(10*sizeof(int)); //10个整型
int i = 0;
for(i=0; i<20; i++) //20个整型
{
*(p+i) = i;
}
free(p);
return 0;
}
虽然用malloc动态开辟空间,那也不能太过分呀,只开辟了40个字节,下面却访问了80个字节,多的40个字节不属于我们,那么这个时候就越界访问了。
3.对非动态开辟内存使用free释放
int main()
{
int *p =(int *) malloc(10*sizeof(int)); //10个整型
int i = 0;
int a = 10;
for(i=0; i<20; i++) //20个整型
{
*(p+i) = i;
}
p = &a; //
free(p);
return 0;
}
这里存在两个问题:
问题一: p在这里并不是存的动态内存开辟的地址,那下面free的p也不是动态内存开辟的空间,而是a,我们发现a并不是动态内存开辟的,所以这里就出现了
对非动态开辟内存使用free释放。
问题二: 我们正儿八经动态开辟的空间却没有得到释放,所以就内存泄漏了。(动态内存开辟出来之后,不用,也不还,找不到,释放不了就是内存泄漏。)
4.使用free释放一块动态开辟内存的一部分
int main()
{
int *p =(int *) malloc(10*sizeof(int)); //10个整型
int i = 0;
for(i=0; i<5; i++)
{
*p++ = i; //*p拿到一块空间,再++,拿到下一块空间。
}
free(p);
return 0;
}
这时候free的p,不再指向动态内存的起始位置,p指向的是第6块空间,如果从这里开始释放就释放的其中的一部分,这时候就会出现错误。
5.对同一块动态内存多次释放
int main()
{
int *p = (int *)malloc(10*sizeof(int));
if(p==NULL)
{
//报错
return 0;
}
//开辟成功,并使用
free(p);
//...
free(p);
reutrn 0;
}
这里出现的错误是重复释放,。
想要避免这类问题出现,可以在free(p)之后,将p = NULL;
6.动态开辟内存忘记释放(内存泄漏)
void test()
{
int *p = (int*)malloc(100);
if(NULL != p)
{
*p = 20;
}
}
int main()
{
test();
while(1);
}
忘记释放不再使用的动态开辟的空间会造成内存泄漏。
解决办法:malloc 和 free 一定要成对使用。
切记:
动态开辟的空间一定要释放,并且正确释放。