C语言指针理解 --- 代码配合图形讲解内存四区

简介: C语言指针理解 --- 代码配合图形讲解内存四区
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修饰的局部变量放在栈区)
  1.    全局区再细分一点分为bss段和data段,bss段存放的是未初始化的全局变量和未初始化的静态变量,已经初始化的全局变量和已经初始化的静态变量存放在data段。
  • 栈区:存放临时变量(包括语句块内的变量、函数参数等),由编译器管理开辟和释放
  • 堆区:malloc的变量,由程序员管理开辟和释放

2. 结合上面的code和画图示意的看,彻底搞懂内存四区模型。

相关文章
|
1月前
|
存储 编译器 程序员
【C语言】内存布局大揭秘 ! -《堆、栈和你从未听说过的内存角落》
在C语言中,内存布局是程序运行时非常重要的概念。内存布局直接影响程序的性能、稳定性和安全性。理解C程序的内存布局,有助于编写更高效和可靠的代码。本文将详细介绍C程序的内存布局,包括代码段、数据段、堆、栈等部分,并提供相关的示例和应用。
45 5
【C语言】内存布局大揭秘 ! -《堆、栈和你从未听说过的内存角落》
|
1月前
|
存储 NoSQL 编译器
【C语言】指针的神秘探险:从入门到精通的奇幻之旅 !
指针是一个变量,它存储另一个变量的内存地址。换句话说,指针“指向”存储在内存中的某个数据。
84 3
【C语言】指针的神秘探险:从入门到精通的奇幻之旅 !
|
1月前
|
存储 编译器 C语言
【C语言】指针大小知多少 ?一场探寻C语言深处的冒险 !
在C语言中,指针的大小(即指针变量占用的内存大小)是由计算机的体系结构(例如32位还是64位)和编译器决定的。
54 9
|
1月前
|
安全 程序员 C语言
【C语言】指针的爱恨纠葛:常量指针vs指向常量的指针
在C语言中,“常量指针”和“指向常量的指针”是两个重要的指针概念。它们在控制指针的行为和数据的可修改性方面发挥着关键作用。理解这两个概念有助于编写更安全、有效的代码。本文将深入探讨这两个概念,包括定义、语法、实际应用、复杂示例、最佳实践以及常见问题。
45 7
|
1月前
|
存储 缓存 算法
【C语言】内存管理函数详细讲解
在C语言编程中,内存管理是至关重要的。动态内存分配函数允许程序在运行时请求和释放内存,这对于处理不确定大小的数据结构至关重要。以下是C语言内存管理函数的详细讲解,包括每个函数的功能、标准格式、示例代码、代码解释及其输出。
63 6
|
1月前
|
存储 算法 程序员
C 语言递归算法:以简洁代码驾驭复杂逻辑
C语言递归算法简介:通过简洁的代码实现复杂的逻辑处理,递归函数自我调用解决分层问题,高效而优雅。适用于树形结构遍历、数学计算等领域。
|
1月前
|
存储 算法 Java
Java 内存管理与优化:掌控堆与栈,雕琢高效代码
Java内存管理与优化是提升程序性能的关键。掌握堆与栈的运作机制,学习如何有效管理内存资源,雕琢出更加高效的代码,是每个Java开发者必备的技能。
55 5
|
2月前
|
传感器 人工智能 物联网
C 语言在计算机科学中尤其在硬件交互方面占据重要地位。本文探讨了 C 语言与硬件交互的主要方法,包括直接访问硬件寄存器、中断处理、I/O 端口操作、内存映射 I/O 和设备驱动程序开发
C 语言在计算机科学中尤其在硬件交互方面占据重要地位。本文探讨了 C 语言与硬件交互的主要方法,包括直接访问硬件寄存器、中断处理、I/O 端口操作、内存映射 I/O 和设备驱动程序开发,以及面临的挑战和未来趋势,旨在帮助读者深入了解并掌握这些关键技术。
52 6
|
2月前
|
存储 程序员 编译器
C 语言数组与指针的深度剖析与应用
在C语言中,数组与指针是核心概念,二者既独立又紧密相连。数组是在连续内存中存储相同类型数据的结构,而指针则存储内存地址,二者结合可在数据处理、函数传参等方面发挥巨大作用。掌握它们的特性和关系,对于优化程序性能、灵活处理数据结构至关重要。
|
2月前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
65 1