动态内存开辟相关试题
我们此次会介绍关于动态内存开辟的一些试题,错误点,以及原因
1.
void getmemory(char* p)//p也是空指针 { p = (char*)malloc(100);//在堆上开辟100个字节的空间,将这100个字节的起始地址交给了p,p便不再是空指针,但p只是个形式参数, //出了函数便销毁了,使得malloc开辟的空间再也找不到了,内存泄露了 //内存泄露未free释放掉导致strcpy也无法执行,什么都没有 } int main() { char* str = NULL; getmemory(str); strcpy(str, "hello world");//回来后str还是空指针,拷贝不成功 printf(str); return 0; }
修改1.
char *getmemory(char* p)//p也是空指针 { p = (char*)malloc(100); return p;//p的类型是char*,所以getmemory中接收了malloc开辟的空间 } int main() { char* str = NULL; str=getmemory(str);//str接收了p里面的地址 strcpy(str, "hello world"); printf(str);//str就是一个字符指针因此str这样是可以用的 free(str);//使用完进行释放 str = NULL;//再将其制成空指针 return 0; }
修改2.
void getmemory(char** p)//char**二级指针进行接收 { *p = (char*)malloc(100);//p是&str,*p是str, } int main() { char* str = NULL; getmemory(&str);//想让他改变这个str,就将str的地址传过去,str是个指针,&str是个二级指针 strcpy(str, "hello world"); printf(str); free(str); str = NULL; return 0; }
例2.
char*getmemory(void)//返回栈空间地址的问题,出返回就销毁了,而堆上开辟的空间出函数是不销毁的 { char p[] = "hello world";//p是一个局部的数组,进入函数生命周期开始,出函数生命周期结束销毁释放, return p;//p也是一个指针,所以返回类型是char*,p返回的是hello world的起始地址 } void test(void) { char *str = NULL; str = getmemory();//str存的是h首元素地址,接收后那个空间就还给操作系统了 printf(str); } int main() { test(); return 0; }
同类题如1,
int*f1(void)//同样是在栈区开辟的问题 { int x = 10; return(&x);//返回的是没有意义的 }
同类题2.
int*f2(void) { int* ptr;//归结为野指针 *ptr = 10; return ptr; }
例3.
void getmemory(char**p, int num) { *p = (int*)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.
void test() { char* str = (char*)malloc(100); strcpy(str, "hello"); free(str);//改错题应在free后将str置为空指针,而不是将free放到if语句后面 if (str != NULL) { strcpy(str, "hello"); printf(str); } } int main() { test(); return 0; }
同时介绍一下内存中的空间