概述
目录
一、
1.对NULL的指针的解引用操作
int main()
{
int* p = (int*)malloc(20);
*p = 5;
return 0;
}
这个地方如果malloc开辟失败的话,p被赋为空指针,此时就出现了对空指针的解引用操作,这样是错误的。
所以在进行解引用之前应该加上一个判断。
int main()
{
int* p = (int*)malloc(20);
if (p == NULL)
{
return 1;
}
else
*p = 5;
return 0;
}
2.对动态开辟空间的越界访问
int main()
{
int*p=(int*)malloc(20);
if (p == NULL)
{
return 1;
}
int i = 0;
for (; i < 20; i++)
{
*(p + i) = i;
}
free(p);
p = NULL;
}
这里要注意20是20个字节,不是元素,只能访问5个int类型的元素,很容易就造成越界访问。
3.对非动态开辟内存使用free释放
int main()
{
int num = 10;
int* p = #
free(p);
p = NULL;
return 0;
}
这样就是错误的,free只能释放动态开辟内存的空间。
4.使用free释放动态内存的一部分
int main()
{
int* p = (int*)malloc(40);
if (p == NULL)
return 1;
int i = 0;
for (; i < 5; i++)
{
*p = i;
p++;
}
free(p);
p = NULL;
return 0;
}
所以如果要这样的话要先用另外一个指针来存放p。
5.对同一块动态内存多次释放
int main()
{
int* p = (int*)malloc(40);
if (p == NULL)
return 1;
int i = 0;
for (; i < 5; i++)
{
*p = i;
p++;
}
free(p);
//........
//........
free(p);
p = NULL;
return 0;
}
1.在这里我们有可能在free之后没有把指针置为空指针,然后经过了一系列操作后又将该指针使用free释放。
2.如果我们在第一次free之后就将p置为空指针,后面的free接收一个空指针,是不会出现错误的。
3.这也告诉我们要在使用free之后,将该指针置为空指针。
6.动态开辟内存忘记释放(内存泄漏)
int* get_mem()
{
int* p = (int*)malloc(40);
return p;
}
int main()
{
int* ptr = get_mem();
return 0;
}
当我们回到main函数中再继续操作时,很容易就忘记释放在get_mem函数中的动态开辟内存。只顾申请却忘了释放,这样就会导致内存泄漏。
二、面试题讲解
void GetMemory(char* p)
{
p = (char*)malloc(100);
}
void Test(void)
{
char* str = NULL;
GetMemory(str);
strcpy(str, "hello world");
printf(str);
}
int main()
{
Test();
return 0;
}
1.图中可以看出str还是NULL(并且出了GetMemory函数之后,创建的空间就被释放了,p所指向的地址无从查找。)
2.这里就出现了对空指针的解引用操作
3.没有对动态开辟内存释放
解决办法
1.对str传参进行传地址操作
2.return p;
void GetMemory(char** p)
{
*p = (char*)malloc(100);
}
void Test(void)
{
char* str = NULL;
GetMemory(&str);
strcpy(str, "hello world");
printf(str);
//释放
free(str);
str = NULL;
}
char* GetMemory(char* p)
{
p = (char*)malloc(100);
return p;
}
void Test(void)
{
char* str = NULL;
str = GetMemory(str);
strcpy(str, "hello world");
printf(str);
free(str);
str = NULL;
}
2.返回栈空间地址的问题
char* GetMemory(void)
{
char p[] = "hello world";
return p;
}
void Test(void)
{
char* str = NULL;
str = GetMemory();
printf(str);
}
int main()
{
Test();
return 0;
}
所以当str再想去顺着地址寻找字符串的时候,就出错了。str此时是一个野指针。
void GetMemory(char** p, int num)
{
*p = (char*)malloc(num);
}
void Test(void)
{
char* str = NULL;
GetMemory(&str, 100);
strcpy(str, "hello");
printf(str);
}
int main()
{
Test();
//......
return 0;
}
很明显应该在printf语句结束后,使用free来释放之前开辟的动态内存,否则会造成内存泄漏。之后还要将str置为NULL。
void Test(void)
{
char* str = (char*)malloc(100);
strcpy(str, "hello");
free(str);
if (str != NULL)
{
//str是野指针,这里就是非法访问
strcpy(str, "world");
printf(str);
}
}
1.free使用的位置不对,该动态内存后面还要继续使用
2.str判断是否为NULL(即malloc开辟空间是否成功)的位置不对,在判断之前就已经执行了strcpy。
正确的应该为
void Test(void)
{
char* str = (char*)malloc(100);
if (str == NULL)
return;
strcpy(str, "hello");
free(str);
str = NULL;
if (str != NULL)
{
strcpy(str, "world");
printf(str);
}
}
以上就是动态内存的常见错误,还有一些面试题的讲解,希望可以帮到大家,如有错误请指出。
最后
以上就是有魅力电灯胆为你收集整理的【C语言】动态内存的常见错误及面试题的讲解一、二、面试题讲解的全部内容,希望文章能够帮你解决【C语言】动态内存的常见错误及面试题的讲解一、二、面试题讲解所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复