目录
对NULL指针的解引用操作
int main()
{
int* p = (int*)malloc(INT_MAX);
if (p == NULL)
return 0;
int i = 0;
for (i = 0; i < 10; i++)
{
*(p + i) = i;
}
return 0;
}
当一次性开辟字节空间过大时,malloc函数就会开辟失败,并且返回空指针
如果解引用空指针就会导致程序崩溃
解决方法:
使用assert()断言后再使用该指针就可以了
对动态开辟空间的越界访问
int main()
{
char* p = (char*)malloc(10 * sizeof(char));
if (p == NULL)
{
printf("%s\n", strerror(errno));
return 0;
}
//使用
int i = 0;
//for (i = 0; i <= 10; i++)//越界
for(i=0; i<10; i++)
{
*(p + i) = 'a'+i;
}
//释放
free(p);
p = NULL;
return 0;
}
如果上方代码为i<=10就会造成越界
因为i是从0开始,一共开辟了10个字节,到i=10的时候就会访问第11个字节
对非动态开辟内存使用free释放
int main()
{
//int* p = (int*)malloc(40);
//free(p);
//p = NULL;
int a = 10;
int*p = &a;
free(p);//err
p = NULL;
return 0;
}
free()只能释放堆上动态内存开辟的空间,释放不了栈上的空间
使用free释放一块动态开辟内存的一部分
int main()
{
int* p = (int*)malloc(40);
if (p == NULL)
{
printf("%s\n", strerror(errno));
return 0;
}
//使用内存
int i = 0;
//1~5
for (i = 0; i < 5; i++)
{
*p = i+1;
p++;
}
//释放
free(p);
p = NULL;
return 0;
}
如果在p的后续中改变了p的值,就再也找不到这块空间了
解决方法:
使用一个指针记录下一开始p的位置
最后用free()释放这个指针就可以了
对同一块动态内存多次释放
int main()
{
int* p = (int*)malloc(40);
if (p == NULL)
{
printf("%s\n", strerror(errno));
return 0;
}
//使用内存
int i = 0;
//1~5
for (i = 0; i < 5; i++)
{
*(p+i) = i + 1;
}
//释放
free(p);
p = NULL;
free(p);//err
return 0;
}
当free()了一块malloc开辟的内存后,这块内存就是未知的了
再次free()可能会造成严重的问题
所以当free()完之后,立马让该指针等于NULL
这样当第二次使用free()的时候,会传递一个空指针,就什么事情都不会发生了
动态开辟内存忘记释放(内存泄漏)
int* test()
{
int* p = (int*)malloc(100);
if (p == NULL)
{
return 0;
}
//使用
//忘记释放,就会出现内存泄露的问题
//return p;
}
int main()
{
int*ptr = test();
//free(ptr);
return 0;
}
内存泄露会造成系统内存浪费,导致程序越来越卡甚至崩溃
解决方法:
free()
或者等待程序结束