今天在敲代码时,有一个bug一直没有解决,后来进过多次调试才发现是realloc的时候出现了错误,我就查了一下realloc的知识点,发现很多易错点,所以写一篇博客来分享一下这些知识点,就当做复习了。
几道经典题目来分析常见的错误:
例一
void GetMemory(char* p)
{
p = (char*)malloc(100);
}
int main()
{
char* str = NULL;
GetMemory(str);
strcpy(str, "hello world");
printf(str);
}
最终输出结果: 程序崩溃。
原因:虽然GetMemory函数在堆上面开辟了100字节的空间,但是在传参的时候是值传递 ,值传递不会改变实参;所以str任然是一个空指针,所以程序崩掉了。而且malloc开辟的空间没有及时释放,存在内存泄漏的问题。
例二
char* GetMemory()
{
char p[] = "hello world";
return p;
}
int main()
{
char* str;
str=GetMemory();
printf(str);
}
最终输出结果:随机值
原因:因为当调用Getmemory函数的时候,是在栈上面开辟一块空间,在栈上面创建一个数组p,存放“hello world”,返回数组p的起始位置;所以str指向的是数组p 的起始位置,但是当函数出了作用域的时候,栈上面的空间就会被销毁,导致当str再去访问的。
例三
int main()
{
char* str = (char*)malloc(100);
strcpy(str, "hello world");
free(str);
if (str != NULL)
{
strcpy(str, "world");
printf(str);
}
}
输出结果及分析:最终能够输出 world,但是这个程序是错误的,因为当str被释放掉之后,栈上的这块空间的权限返回给系统,然后再去访问就是非法访问了。
例四
int main()
{
char* s = (char*)malloc(10);
s = "hello world";
s = (char*)realloc(s, 100);
printf(s);
}
原因分析:因为s指针是指向开辟在堆上面的内存,而当s=“hello world”的时候,s指向了栈上面的字符串首字母‘ h ’的地址,而用realloc时,他的第一个参数(指向原地址的指针)必须是指向堆区的,所以会出现这样的报错。