题目一
题目描述
//请问代码的运行结果如何? #include <stdio.h> #include <stdlib.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; }
题目答案
什么都不打印,且存在内存泄露。
题目分析
代码改正
有两种方法改正:
一: (让GetMemory返回指针,记得释放内存)
#include <stdio.h> #include <stdlib.h> #include <string.h> 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; } int main() { Test(); return 0; }
二:(传址)
#include <stdio.h> #include <stdlib.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; }
题目二
题目描述
//请问代码运行的结果如何? #include <stdio.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; }
题目答案
打印出随机值,并非hello world。
题目分析
GetMemory函数内部创建的数组是在栈区上的,该函数结束,p数组的空间就还给了操作系统;返回的地址是没有实际的意义的,如果通过返回的地址去访问内存,就是非法访问。
(存放在堆区的话则不会被立刻销毁)
2-1
下面的代码是否出错?
int * func (void) { int * ptr; *ptr = 10; return ptr; }
此处的ptr为野指针,没有经过初始化,使用不了。
故而该代码出错。
题目三
题目描述
//请判断代码是否出错? #include <stdio.h> #include <stdlib.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 world"); printf(str); } int main() { Test(); return 0; }
题目答案
该代码错误,其忘记释放内存空间。
在
后加上
即可
题目四
题目描述
//请判断下面代码是否出错? #include <stdio.h> #include <stdlib.h> #include <string.h> void Test(void) { char * str = (char*)malloc(100); strcpy(str,"hello"); free(str); if(str != NULL) { strcpy(str,"world"); printf(str); } } int main() { Test(); return 0; }
题目答案
出错。str被释放之后还被使用。
题目分析
free函数释放完空间之后是不会帮指针赋值为空,此时再去使用它就会造成非法访问。
所以使用完free函数之后一定要把指针赋为空指针。
C/C++中程序内存区域划分
1.栈区(stack) :在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。钱内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。栈区主要存放运行函数而分配的局部变量、函数参数、返回数据、返回地址等。
2.堆区(heap) : 一般由程序员分配释放,若程序员不释放,程序结束时可能由OS(操作系统)回收。分配方式类似于链表。
3.数据段(静态区) ( static):存放全局变量、静态数据。程序结束后由系统释放。
4.代码段:存放函数体(类成员函数和全局函数)的二进制代码。
实际上普通的局部变量是在栈区分配空间的,栈区的特点是在上面创建的变量出了作用域就销毁。
但是被static修饰的变量存放在数据段(静态区),数据段的特点是在上面创建的变量,直到程序结束才销毁
所以生命周期变长。