一.内存布局

1.1 代码区

代码区code,程序被操作系统加载到内存的时候,所有的可执行代码都加载到代码区,也叫代码段。代码区是可读不可写的。

代码区中的所有的内容在程序加载到内存的时候就确定了,运行期间不可以修改,只可以执行。

1.2 静态区

静态区是程序加载到内存的时候就确定了,程序退出的时候就从内存消失。所有的全局变量静态变量在程序运行期间都占用内存。静态区是可读可写的。

1.3 栈区

栈stack是一种先进后出的内存结构,所有的自动变量函数的形参函数的返回值都是由编译器自动放出栈中,当一个自动变量超出其作用域时,自动从栈中弹出

栈区的容量一般很小,单位一般是k,所以栈中不能有太多变量。不同的系统栈的大小是不一样的,Windows系统在编译的时候就可以指定栈的大小,Linux栈的大小是可以通过环境变量设置的。

1.4 堆区

堆heap和栈一样,也是一种在程序运行过程中可以随时修改的内存区域,但没有栈那样先进后出的顺序。堆是一个大容器,它的容量要远远大于栈,但是在C语言中,堆内存空间的申请和释放需要手动通过代码来完成。

堆内存有一个最小单位,叫内存页,一个内存页的大小也不是固定的。

在当前测试的这个机器里面是4k为一个单位变化的,当我们需要申请一个堆内存的时候,总是以4k为一个单位,要一个char,给的是4k,操作系统这样做可以避免频繁分配内存。

堆的分配和释放

二.标准C内存函数

☞ malloc

☞ free

☞ calloc

☞ realloc

例1:malloc和free的使用

#include <stdio.h> // 这个头文件在系统目录下
#include <stdlib.h> // 使用了system函数
#include <Windows.h>
#include <string.h> // 使用了memset函数 int main() { //int a = 0; // 在栈区
//static int b = 1; // 在静态区
//int array[10]; // 在栈区
//int sss[100000];// 不能在栈里面放太大的元素 // 堆内存
char *p;
p = malloc(); // 在堆中分配了一个100个字节的内存,p指向堆内存的首地址。p在栈里面,但p的值是堆地址编号 // !!!!堆内存使用完毕后需要进行释放
free(p); // 把p指向的堆空间翻译 // 在堆中分配一个int
int *p1 = malloc(sizeof(int)); // 在堆中分配一个int大小的内存
*p1 = ;//把堆中int的值设置为0
printf("%d\n",*p1); // 在堆中分配一个int数组
int *p2 = malloc(sizeof(int)*);
memset(p2,,sizeof(int)*); // 将这段内存的值初始化为0 for (int i = ; i < ; i++) {
printf("%d\n",p2[i]);
} free(p1);
free(p2); system("pause");
return ; }

 例2:malloc和calloc的区别:

#include <stdio.h> // 这个头文件在系统目录下
#include <stdlib.h> // 使用了system函数
#include <Windows.h>
#include <string.h> // 使用了memset函数 int main() { char *p1 = malloc(*sizeof(char)); // malloc只负责分配不负责清理,因此在内存分配完成后,调用memset(x,0,x)进行初始化
char *p2 = calloc(,sizeof(char)); // calloc分配内存的同时会把内存清空,即会将所有内存置为0 for (int i = ; i < ; i++) {
printf("%x\n",p1[i]);
} printf("--------------------------------\n"); for (int i = ; i < ; i++) {
printf("%x\n",p2[i]);
} system("pause");
return ; }

执行结果:

例3:realloc的使用

#include <stdio.h> // 这个头文件在系统目录下
#include <stdlib.h> // 使用了system函数
#include <Windows.h>
#include <string.h> // 使用了memset函数 int main() { char *s1 = malloc( * sizeof(char));
memset(s1, , * sizeof(char)); //使用malloc分配的内存最好初始化
strcpy(s1, "");
printf("当前s1的值为:%s\n", s1); char *s2 = calloc(, sizeof(char)); // 分配10个内存单元,每个内存单元1字节
strcpy(s2, "abcdef");
printf("当前s2的值为:%s\n", s2); // 需求:把s1和s2合并为一个字符串,结果放入s1
int len1 = strlen(s1);
int len2 = strlen(s2);
// realloc的返回值是指向新空间的指针,如果错误则返回NULL
s1 = realloc(s1, len1 + len2 + ); // 重新为s1分配内存,+1的目的是字符串末尾还有一个\0的结束符,strlen求得的实际上是字符的总数
strcat(s1, s2); printf("当前s1的值为:%s\n", s1); free(s1);
free(s2); system("pause");
return ; }

执行结果:

C语言基础(18)-内存的更多相关文章

  1. Java入门 - 语言基础 - 18.正则表达式

    原文地址:http://www.work100.net/training/java-regular-expression.html 更多教程:光束云 - 免费课程 正则表达式 序号 文内章节 视频 1 ...

  2. C++语言基础(18)-模板

    Java中的泛型编程可以极大的提升编程的效率,比如在android中查找一个控件的ID:标准写法为: TextView tv_text = (TextView)findViewById(R.id.tv ...

  3. c语言基础学习08_关于内存管理的复习

    =============================================================================对于c语言来讲,内存管理是一个很重要的内容,它 ...

  4. 数据结构基础(1)--数组C语言实现--动态内存分配

    数据结构基础(1)--数组C语言实现--动态内存分配 基本思想:数组是最常用的数据结构,在内存中连续存储,可以静态初始化(int a[2]={1,2}),可以动态初始化 malloc(). 难点就是数 ...

  5. GO学习-(18) Go语言基础之并发

    Go语言基础之并发 并发是编程里面一个非常重要的概念,Go语言在语言层面天生支持并发,这也是Go语言流行的一个很重要的原因. Go语言中的并发编程 并发与并行 并发:同一时间段内执行多个任务(你在用微 ...

  6. php面试题之三——PHP语言基础(基础部分)

    三.PHP语言基础 1. strlen( )与 mb_strlen( )的作用分别是什么(新浪网技术部) strlen和mb_strlen都是用于获取字符串长度. strlen只针对单字节编码字符,也 ...

  7. C语言基础(转载自大海笔记)

    # C语言基础2015年03月26日10:04:411.    语言排行榜C——java——objective-C2.    进制:进制:进位机制.用普通的话讲,应该为人为的定义一种度量来标识一样东西 ...

  8. Go语言基础之结构体

    Go语言基础之结构体 Go语言中没有“类”的概念,也不支持“类”的继承等面向对象的概念.Go语言中通过结构体的内嵌再配合接口比面向对象具有更高的扩展性和灵活性. 类型别名和自定义类型 自定义类型 在G ...

  9. js-day01-js语言基础

    JavaScript简介:JavaScript一种直译式脚本语言,是一种动态类型.弱类型.基于原型的语言,内置支持类型.它的解释器被称为JavaScript引擎,为浏览器的一部分,广泛用于客户端的脚本 ...

随机推荐

  1. 【线性筛】【筛法求素数】【素数判定】URAL - 2102 - Michael and Cryptography

    暴力搞肯定不行,因此我们从小到大枚举素数,用n去试除,每次除尽,如果已经超过20,肯定是no.如果当前枚举到的素数的(20-已经找到的质因子个数)次方>剩下的n,肯定也是no.再加一个关键的优化 ...

  2. 【权值分块】bzoj3570 DZY Loves Physics I

    以下部分来自:http://www.cnblogs.com/zhuohan123/p/3726306.html 此证明有误. DZY系列. 这题首先是几个性质: 1.所有球质量相同,碰撞直接交换速度, ...

  3. TZOJ 5396: 集五福过大年

    描述 又是一年春来到,伴随着春节,支付宝的“集五福”活动又开始了,五福分别是“爱国福”.“富强福”.“和谐福”.“友善福”和“敬业福”,五张不同的福卡可以合成一张“五福到”,crq也扫了不少福,这么多 ...

  4. GAILS里面的SAVE方法

    用途 保存一个domain类的实例到数据库,需要的话会级联保存所有的子实例. 举例 def b = new Book(title:"The Shining") b.save() 描 ...

  5. linux下查看端口占用情况以及服务启动的目录

    1.先介绍几个命令: 1. lsof -i:80 查看80端口的占用情况 命令返回结果: COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME ngin ...

  6. OC语言基础之类的本质

    一.类的本质 1: // 类本身也是一个对象,是个Class类型的对象,简称类对象 2: 3: /* 4: 利用Class 创建 Person类对象 5: 6: 利用 Person类对象 创建 Per ...

  7. 如何让vs2017 EF实体生成支持Mysql 和 Oracle?

    1.Mysql 安装   MySql Connector/Net        https://dev.mysql.com/downloads/connector/net/ 安装    mysql f ...

  8. [Android Pro] 通过Android trace文件分析死锁ANR

    转载自: http://blog.csdn.net/oujunli/article/details/9102101#reply 对于从事Android开发的人来说,遇到ANR(Application ...

  9. python 推导式(Comprehensions)

    一.介绍 列表推导(list comprehensions) 这是一种将for循环.if表达式以及赋值语句放到单一语句中的一种方法.换句话说,你能够通过一个表达式对一个列表做映射或过滤操作. 一个列表 ...

  10. 常见BUG问题汇总[待更新]

    1.字符串数据库长度问题,特别是与java接口对接的过程中要注意 2.存储数据库之前所有的数据都需要在存储前进行验证