1.对NULL指针的解引用操作
问题:当我们用malloc开辟动态内存失败时,指针将会是空指针。 一般申请的内存过大将会导致开辟动态内存失败。 看下面这个例子
void test()
{
int* p = (int*)malloc(INT_MAX);
*p = 20;
free(p);
}
调用这个函数,并监视p 可以看到,p的值是0,也就是空指针。 解决: 所以,我们在申请动态内存空间后,要判断它是否不为空指针,才进行一系列的操作。避免程序出现问题。
void test()
{
int* p = (int*)malloc(INT_MAX);
if (NULL == p)
{
perror("malloc");
return;
}
else
{
*p = 20;
}
free(p);
p = NULL;
}
2.对动态开辟空间的越界访问
问题: 同数组一样,动态开辟的内存空间也可能被越界访问。
void test2()
{
int* p = (int*)malloc(5 *sizeof(int));
if (NULL == p)
{
perror("malloc");
return;
}
else
{
for (int i = 0; i < 10; i++)
{
*(p + i) = i;
}
}
free(p);
p = NULL;
}
调用这个函数 程序直接崩溃。 解决:
void test2()
{
int* p = (int*)malloc(5 * sizeof(int));
if (NULL == p)
{
perror("malloc");
return;
}
else
{
for (int i = 0; i < 5; i++)
{
*(p + i) = i;
}
}
free(p);
p = NULL;
}
1.尽量不要越界访问 2.可以在存满的情况下加个realloc
3.对非动态内存开辟使用free释放
问题:很多人刚学malloc的时候,知道malloc后一定要free释放,避免内存泄漏。 但是却常常走火入魔,写完一段程序就free,即使代码里面没有开辟动态内存。 比如:
int main()
{
int a = 10;
int* p = &a;
free(p);
p = NULL;
return 0;
}
运行程序,直接崩溃 解决: free()是释放动态开辟的内存空间,不是什么都能释放的。
4.使用free释放动态开辟内存的一部分
free()释放动态开辟的内存空间的时候,括号里面放的是一定开辟空间的起始地址。 问题: 看下面这一段代码有什么问题?
int main()
{
int* p = (int*)malloc(20);
if (NULL == p)
{
return 1;
}
for (int i = 0; i < 5; i++)
{
*p = i;
p++;
}
free(p);
p = NULL;
return 0;
}
运行程序,程序也会崩溃。因为free(p),p不再指向空间的起始地址。 解决:
int main()
{
int* p = (int*)malloc(20);
if (NULL == p)
{
return 1;
}
for (int i = 0; i < 5; i++)
{
*(p + i) = i;
}
free(p);
p = NULL;
return 0;
}
int main()
{
int* p = (int*)malloc(20);
if (NULL == p)
{
return 1;
}
int* p2 = p;
for (int i = 0; i < 5; i++)
{
*p = i;
p++;
}
free(p2);
p = NULL;
p2 = NULL;
return 0;
}
5.对同一块动态内存多次释放
问题:有时候我们写程序的时候,可能会因为粗心多次free了一个动态开辟的内存。 这就体现了free后,把指针置为空的重要性
int main()
{
int* p = (int*)malloc(20);
if (NULL == p)
{
return 1;
}
for (int i = 0; i < 5; i++)
{
*(p + i) = i;
}
free(p);
free(p);
}
运行程序,程序崩溃。 解决:
int main()
{
int* p = (int*)malloc(20);
if (NULL == p)
{
return 1;
}
for (int i = 0; i < 5; i++)
{
*(p + i) = i;
}
free(p);
p = NULL; 把p置为空指针
free(p);
}
6.动态开辟内存忘记释放(内存泄漏)
比上面那些问题更严重的问题就是忘记释放,就会造成内存泄漏问题
void test()
{
int* p = (int*)malloc(100);
if (NULL != p)
{
*p = 20;
}
}
int main()
{
test();
while (1);
}
大家可以运行这段程序,然后打开任务管理器看一下自己的程序CPU占比,不过不会一直升高,因为有自动保护机制。 解决: 正确的free动态开辟的内存空间。
总结:
对于动态开辟内存malloc,我们既然要向内存使用他的方便之处,就要懂得在使用完后怎么规范地还给内存。 有借有还,再借不难!
|