1. #define _CRT_SECURE_NO_DEPRECATE 2. 3. #include "stdlib.h" 4. #include "string.h" 5. #include "stdio.h" 6. 7. 8. //c++编译器优化 9. char *getStr1() 10. { 11. char *p = "abcd1"; //这里定义的abcd1放在全局区 12. return p; 13. } 14. 15. char *getStr2() 16. { 17. char *p = "abcd1"; //这里定义的abcd1也放在全局区,因为上面已经定义了abcd1,所以这里的abcd1不再重新分配内存 18. return p; 19. } 20. 21. char *getStr3() 22. { 23. char buf[100]; 24. memset(buf, 0, sizeof(buf)); 25. strcpy(buf, "abcd1"); 26. return buf; 27. } 28. 29. 30. //在被调用函数里面malloc的内存,首地址传给调用函数有两种方法: 31. /* 32. 1、return :下面的getStr就是实例 33. 2、指针做函数参数 34. */ 35. char *getStr4() 36. { 37. char *p = NULL; //p是分配在栈区的,但是p指向的内存空间的变量是分配在堆区的 38. p = (char *)malloc(100);//在堆上分配100字节的空间 39. 40. strcpy(p, "abcdefg"); //这句话的理解 41. //先在全局区的常量区分配一块内存,放置abcdefg, 42. //然后将abcdefg拷贝到上一步堆上分配的空间中 43. 44. return p; 45. } 46. 47. 48. void main(void) 49. { 50. int a = 0; 51. char *p1 = NULL; 52. char *p2 = NULL; 53. char *p3 = NULL; 54. p3 = (char *)malloc(100); 55. p1 = getStr1(); 56. p2 = getStr2(); 57. 58. printf("getStr2():%s....\n", getStr2()); 59. 60. //这里调用getStr3输出的是乱码,是因为buf是分配在栈区的, 61. //调用getStr3结束之后buf分配的空间就会被销毁,所以无法返回 62. printf("getStr3():%s\n", getStr3()); 63. 64. //这里调用getStr4之后,是可以正确的返回的, 65. printf("getStr4():%s\n", getStr4()); 66. 67. printf("p1:%d....\n", p1); 68. printf("p2:%d....\n", p2); 69. system("pause"); 70. } 71.
getStr4内存模型图
总结:
1. 内存四区分别为:代码区、全局区、堆区、栈区
- 代码区的特点:共享和只读
- 存放在全局区的有:全局变量、静态变量(包括全局静态变量和局部静态变量)、常量(字符串常量和const修饰的全局变量,const修饰的局部变量放在栈区)
- 全局区再细分一点分为bss段和data段,bss段存放的是未初始化的全局变量和未初始化的静态变量,已经初始化的全局变量和已经初始化的静态变量存放在data段。
- 栈区:存放临时变量(包括语句块内的变量、函数参数等),由编译器管理开辟和释放
- 堆区:malloc的变量,由程序员管理开辟和释放
2. 结合上面的code和画图示意的看,彻底搞懂内存四区模型。