C语言内存四区模型学生笔记|“朝闻道”知识分享大赛

2301_80948168 2024-10-31 19:24:09

这是我参加朝闻道知识分享大赛的第十篇文章


C语言内存四区模型学生笔记

目录

C语言内存四驱模型学生笔记

一、概述

二、栈区(Stack)

三、堆区(Heap)

四、数据区(Data)

五、代码区(Code)

六、总结


一、概述

C语言内存四驱模型是C语言学习过程中一个重要的概念,它帮助程序员理解程序在内存中的布局和分配情况。通过理解内存四驱模型,可以更好地掌握C语言指针、变量作用域和内存管理等方面的知识。内存四驱模型将内存划分为四个区域:栈区、堆区、数据区和代码区。

二、栈区(Stack)

栈区是内存中的一个重要区域,用于存放函数的参数值、局部变量的值等。栈区的操作方式类似于数据结构中的栈,具有先进后出的特性。栈区由编译器自动分配和释放内存,当函数执行完毕后,栈区中的内存会自动被回收。

  1. 栈区的特性

    • 先进后出:栈区中的内存分配和释放遵循先进后出的原则,即最后分配的内存最先被释放。
    • 自动管理:栈区的内存由编译器自动分配和释放,程序员不需要手动干预。
    • 局部变量:函数中的局部变量通常存放在栈区,包括函数的参数。
  2. 栈区的示例

#include <stdio.h> 


void change1(int a) { 
a = 200; 
} 


void change2(int *a) { 
*a = 200; 
} 


int main() { 
int a = 100; 
int b = 10; 
change1(b); 
change2(&a); 
printf("change1 = %d, change2 = %d\n", b, a); 
return 0; 
}


在上面的示例中,a 和 b 是局部变量,存放在栈区。change1 函数中的参数 a 也是局部变量,存放在栈区。由于 change1 函数中的 a 是值传递,因此不会改变 main 函数中的 b 的值。而 change2 函数中的参数是 a 的地址,通过地址修改 a 的值,因此 main 函数中的 a 的值被改变。

  1. 栈区的内存分配和释放

当函数被调用时,编译器会在栈区分配内存给函数的局部变量和参数。当函数执行完毕后,这些内存会自动被释放。因此,栈区中的内存不需要程序员手动管理,也不会出现内存泄漏的问题。

三、堆区(Heap)

堆区是内存中的另一个重要区域,用于动态分配内存。堆区的内存由程序员手动分配和释放,如果没有正确释放,可能会导致内存泄漏。

  1. 堆区的特性

    • 动态分配:堆区的内存需要程序员手动分配和释放,通常使用 malloccallocrealloc 和 free 等函数。
    • 手动管理:程序员需要负责堆区内存的分配和释放,以避免内存泄漏。
    • 灵活性:堆区可以动态分配任意大小的内存,适合存储大小不确定的数据。
  2. 堆区的示例

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 


char* getMem() { 
char *p1 = NULL; 
p1 = (char*)malloc(sizeof(char) * 10); // 申请内存空间 
return p1; 
} 


int main() { 
char *tmp = NULL; 
tmp = getMem(); 
strcpy(tmp, "aaabbb"); // 向 tmp 指向的内存空间中拷贝数据 
printf("hello..tmp: %s.\n", tmp); 
free(tmp); // 释放内存 
return 0; 
}


在上面的示例中,getMem 函数使用 malloc 函数在堆区分配了 10 个字节的内存,并返回这块内存的指针。在 main 函数中,使用 strcpy 函数将字符串 "aaabbb" 拷贝到这块内存中,并打印出来。最后,使用 free 函数释放这块内存,以避免内存泄漏。

  1. 堆区的内存分配和释放

在堆区分配内存时,通常使用 malloccalloc 或 realloc 函数。malloc 函数用于分配指定大小的内存块,并返回一个指向该内存块的指针。calloc 函数用于分配内存并初始化所有位为 0。realloc 函数用于调整已分配内存块的大小。

释放堆区内存时,使用 free 函数。free 函数接受一个指向已分配内存块的指针,并释放这块内存。如果忘记释放堆区内存,可能会导致内存泄漏,即这块内存将永远无法被回收。

四、数据区(Data)

数据区用于存放全局变量、静态变量和常量字符串等。数据区通常分为常量区和全局区/静态区。

  1. 常量区

常量区用于存放常量,通常是字符串常量。在 C 语言中,字符串常量在编译时会被存储在常量区,并且编译器会对相同的字符串常量进行优化,使它们共享同一块内存。

#include <stdio.h> 


char* getStr1() { 
char *p1 = "aaaaa"; 
return p1; 
} 


char* getStr2() { 
char *p2 = "aaaaa"; 
return p2; 
} 


int main() { 
char *p1 = NULL; 
char *p2 = NULL; 
p1 = getStr1(); 
p2 = getStr2(); 
printf("p1: %s , p2: %s\n", p1, p2); 
printf("p1: %p , p2: %p\n", (void*)p1, (void*)p2); 
return 0; 
}

全局区/静态区在上面的示例中,getStr1 和 getStr2 函数都返回指向字符串 "aaaaa" 的指针。由于字符串 "aaaaa" 是常量,编译器会对其进行优化,使 p1 和 p2 指向同一块内存。因此,打印出的地址是相同的。

全局区/静态区用于存放全局变量和静态变量。全局变量是在函数外部声明的变量,它们在程序的整个生命周期内都存在。静态变量是在函数内部使用 static 关键字声明的变量,它们在函数调用之间保持其值。

#include <stdio.h> 


int globalVar = 100; // 全局变量 


void func() { 
static int staticVar = 200; // 静态变量 
printf("globalVar = %d, staticVar = %d\n", globalVar, staticVar); 
staticVar++; 
} 


int main() { 
func(); 
func(); 
return 0; 
}

 

五、代码区(Code)

在上面的示例中,globalVar 是一个全局变量,它在程序的整个生命周期内都存在。staticVar 是一个静态变量,它在 func 函数调用之间保持其值。因此,每次调用 func 函数时,staticVar 的值都会递增。

代码区用于存放程序的二进制代码,即机器指令。代码区在程序加载到内存时由操作系统创建,并且在程序运行期间不可修改。

  1. 代码区的特性

    • 只读性:代码区中的内存是只读的,不能修改其中的内容。如果尝试修改代码区的内容,会导致程序崩溃。
    • 固定大小:代码区的大小在程序编译时确定,并在程序加载到内存时由操作系统分配。
  2. 代码区的示例

#include <stdio.h> 


void hello() { 
printf("Hello, World!\n"); 
} 


在上面的示例中,hello 函数和 main 函数的二进制代码都被存储在代码区中。当程序运行时,操作系统将代码区加载到内存中,并跳转到 main 函数的入口点开始执行。

六、总结

C语言内存四驱模型将内存划分为栈区、堆区、数据区和代码区四个区域。每个区域都有其特定的用途和特性。栈区用于存放函数的参数和局部变量,由编译器自动分配和释放内存。堆区用于动态分配内存,需要程序员手动管理。数据区用于存放全局变量、静态变量和常量字符串等。代码区用于存放程序的二进制代码,是只读且固定大小的。

通过理解内存四驱模型,可以更好地掌握C语言中的内存管理、变量作用域和指针等方面的知识。这对于编写高效、可靠的C程序具有重要意义。同时,也有助于理解C语言程序在内存中的布局和运行过程,从而能够更好地进行程序调试和优化。

...全文
36 回复 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

1,040

社区成员

发帖
与我相关
我的任务
社区描述
中南民族大学CSDN高校俱乐部聚焦校内IT技术爱好者,通过构建系统化的内容和运营体系,旨在将中南民族大学CSDN社区变成校内最大的技术交流沟通平台。
经验分享 高校 湖北省·武汉市
社区管理员
  • c_university_1575
  • WhiteGlint666
  • wzh_scuec
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

欢迎各位加入中南民族大学&&CSDN高校俱乐部社区(官方QQ群:908527260),成为CSDN高校俱乐部的成员具体步骤(必填),填写如下表单,表单链接如下:
人才储备数据库及线上礼品发放表单邀请人吴钟昊:https://ddz.red/CSDN
CSDN高校俱乐部是给大家提供技术分享交流的平台,会不定期的给大家分享CSDN方面的相关比赛以及活动或实习报名链接,希望大家一起努力加油!共同建设中南民族大学良好的技术知识分享社区。

注意:

1.社区成员不得在社区发布违反社会主义核心价值观的言论。

2.社区成员不得在社区内谈及政治敏感话题。

3.该社区为知识分享的平台,可以相互探讨、交流学习经验,尽量不在社区谈论其他无关话题。

试试用AI创作助手写篇文章吧