动态内存经典笔试题分析
目录
1.题目一
2.题目二
3.题目三
4.题目四
1.题目一
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
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;
}
请问运行Test 函数会有什么样的结果?
程序崩溃。出了函数,局部变量p已经销毁,函数返回后,str依然为空指针,把hello world拷贝放到空指针指向的空间去,拷贝必然存在对空指针的解引用操作,程序就会崩溃。
这部分代码要表达的意思其实是想把malloc开辟的100个字节的空间的地址传给str,接着拷贝内容。上面代码由于采用值传递,形参是实参的一份临时拷贝,导致创建形参p,对形参p的修改不会影响实参。
正确写法:
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
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;
}
int main()
{Test();return 0;
}
运行结果:
2.题目二
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
char* GetMemory(void)
{char p[] = "hello world";return p;
}
void Test(void)
{char* str = NULL;str = GetMemory();//函数返回的是局部变量的地址printf(str);
}
int main()
{Test();return 0;
}
请问运行Test 函数会有什么样的结果?
运行结果:
可能正常打印,也可能程序崩溃。出了GetMemory函数,数组p销毁,p指向的内存空间已经还给操作系统了,这是返回栈空间地址的问题。函数返回后,str接收的就是野指针。
情况1:当跳出函数后,恰好p指向的空间没有被操作系统使用,就可以打印出来hello world。
情况2:当跳出函数后,p指向的空间已经被覆盖了,就不能完成任务。
情况1:
情况2:
3.题目三
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
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;
}
以上代码有什么问题?
运行结果:
没有释放空间。
正确写法:
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
void GetMemory(char** p, int num)
{*p = (char*)malloc(num);
}
void Test(void)
{char* str = NULL;GetMemory(&str, 100);strcpy(str, "hello");printf(str);free(str);str = NULL;
}
int main()
{Test();return 0;
}
4.题目四
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
void Test(void)
{char* str = (char*)malloc(100);strcpy(str, "hello");free(str); //str没有置为空指针if (str != NULL){strcpy(str, "world");printf(str);}
}
int main()
{Test();return 0;
}
请问运行Test 函数会有什么样的结果?
运行结果:
通过free把str指向的空间释放掉,那块空间已经还给操作系统了,我们已经没有使用权限了,但是str仍然指向那块空间。 strcpy函数拷贝时,str是野指针,world\0把hello\0覆盖掉,造成非法访问(篡改)内存。所以要把str置为空。