8种机械键盘轴体对比

本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?

为什么会出现动态内存分配

这个问题要结合数组来进行讨论。在C99之前的标准中,C语言中数组的定义要求必须给定常量的大小才能定义数组,也就是说数组变量的内存空间在编译时就已成定局,无法更改。那我们如果想要申请一块内存空间,空间大小在运行时才进行确定该怎么做呢?这就要用到动态的内存分配了,这里的空间大小的确定是在运行时才进行确定的。

动态内存分配函数

malloc和free

在内存的动态分配中,首当其冲最为重要的两个函数就是malloc和free函数,它们挑起了动态内存分配的大梁。

malloc函数负责向计算机申请一块连续的内存空间,并且返回指向该块内存的指针。

void* malloc(size_t size);

但是值得注意的是malloc所返回的指针的类型是void*型,所以在实际使用中我们往往要进行牵制类型转换将其转换为我们想要的指针类型。关于这个函数还有以下几点说明。

1、如果开辟空间成功则返回一个指向该空间的指针。

2、如果开辟空间失败则返回NULL。

3、如果参数为0则是未定义行为。

4、返回类型为void*所以编译器并不知道所开辟的空间的类型,由使用者决定。

既然开辟了空间,并且这个空间编译器不会帮我们自动将其释放那么就必然要求我们在使用完毕后将其释放,不浪费内存空间不造成泄露,因此就出现了free函数。

void free (void* ptr);

1、如果参数ptr的不是动态开辟的则行为是未定义的。

2、如果参数ptr == NULL则函数什么都不做。

malloc和free函数都在stdlib.h头文件中。

以下举一个动态分配内存并且释放的例子。1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38#include

#include

int main()

{

int n = 0;

printf("请输入要分配的数组的内存空间的大小:");

scanf("%d", &n);

int* array = (int*)malloc(sizeof(int) * n);

printf("分配成功!n");

printf("请给数组赋值:");

for(int i = 0; i < n; i++)

{

scanf("%d", &array[i]);

}

for(int i = 0; i < n; i++)

{

printf("%dt", array[i]);

}

printf("n");

free(array);

array = NULL;

printf("数组已经释放!n");

}

请输入要分配的数组的内存空间的大小:8

分配成功!

请给数组赋值:1

2

3

4

5

6

7

8

12345678

数组已经释放!

在以上这个例子中我们动态地在程序运行时对一个数组进行了空间的分配,并且让用户对数组进行了赋值,之后打印,数组使用完毕后我们又用free函数将其空间释放。这是一个很简单但是很实用的动态内存分配的例子。在这个例子中要尤为记住的一点是我们在进行动态的内存分配后一定不能忘记在使用完毕后将内存空间释放,并且将指针赋值为NULL,这一点是十分关键的,否则将造成内存泄漏和野指针,对程序造成很大的影响。

往往内存泄漏不是我们忘记free而是不经意间造成的,以下就是一个典型的内存泄漏的例子。1

2

3

4

5

6

7

8

9#include

#include

int main()

{

int* p = (int*)malloc(sizeof(int));

p = (int*)malloc(sizeof(int));

free(p);

p = NULL;

}

这个例子中我们明明进行了释放却也造成了内存泄漏,这是因为我们申请了两次内存空间,但是用同一个指针来接收,只释放了一次,因此造成了内存的泄漏。因此我们在实际使用中牵扯动态内存分配的时候都一定要小心又小心。

calloc

C语言还提供了一个函数进行动态内存分配。这个函数与malloc函数很相似,但是有一点不同的是这个函数会自动进行初始化。但是初始化有时候也不尽然全是好事,当我们要申请一个特别大的空间时,初始化会浪费很多很多的时间。

void* calloc(size_t num, size_t size);

calloc的功能是分配num个大小为size的内存空间,并将内存空间初始化为0。举个例子。1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26#include

#include

int main()

{

int n = 0;

printf("请输入数组长度:");

scanf("%d", &n);

int* array = (int*)calloc(n, sizeof(int));

for(int i = 0; i < n; i++)

{

printf("%dn", array[i]);

}

free(array);

}

请输入数组长度:8

0

0

0

0

0

0

0

0

在以上这个例子中我们看到calloc确实可以进行动态内存分配并且进行了初始化,但是这也是又两面性的。因此也要谨慎使用。

realloc

当我们将内存空间进行动态分配后我们如果想要扩大我们分配的内存该怎么做呢?我们可以分配一块新的内存然后将原来内存中的数据再放到新的内存中。但是在C语言标准库中为了方便已经给我们准备了这么一个扩容函数realloc。

void* realloc(void* ptr, size_t size);

ptr是要调整大小的内存空间,size是调整后的大小。至于计算机是怎么进行扩容的呢?这里要分两种情况。

1、如果目标内存空间后面有足够大小的空间则直接将后面的空间归入目标空间中即可。

2、如果目标空间后面没有足够大小的空间则在内存中重新寻找一片足够大小的空间进行开辟并且将原来的数据放入到新的空间中。1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45#include

#include

int main()

{

int n = 0;

printf("请输入数组的长度:");

scanf("%d", &n);

int* array = (int*)malloc(sizeof(int) * n);

printf("请输入目标扩容的大小:");

scanf("%d", &n);

array = (int*)realloc(array, n * sizeof(int));

printf("扩容成功!n");

printf("请给数组赋值:");

for(int i = 0; i < n; i++)

{

scanf("%d", &array[i]);

}

printf("打印数组:");

for(int i = 0; i < n; i++)

{

printf("%dn", array[i]);

}

}

请输入数组的长度:5

请输入目标扩容的大小:8

扩容成功!

请给数组赋值:1

2

3

4

5

6

7

8

打印数组:1

2

3

4

5

6

7

8

以上这个例子我们成功对已经分配的内存空间进行了扩容。

常见动态内存错误

1、对NULL指针的解引用操作。

2、对动态开辟空间越界访问。

3、对非动态内存使用free释放。

4、释放一块动态开辟内存的一部分。

5、对同一块内存多次释放。

6、动态开辟内存忘记释放。

以上的错误都是十分常见的,因此我们在对内存进行操作的时候一定要万分小心。

C/C++程序内存开辟

在这里将详细介绍下计算机内存中的几个区域。

1. 栈区(stack):在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些

存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有

限。 栈区主要存放运行函数而分配的局部变量、函数参数、返回数据、返回地址等。

2. 堆区(heap):一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。分配方式类似

于链表。

3. 数据段(静态区)(static)存放全局变量、静态数据。程序结束后由系统释放。

4. 代码段:存放函数体(类成员函数和全局函数)的二进制代码。

通常我们定义的变量都存在栈区,动态分配内存时变量的空间都是在堆区上进行分配的,堆区有着更大更充足的空间。由此一来我们对动态内存分配就有了更深的了解。

柔性数组

柔性数组是在C99中最新的语法,其允许在结构体中最后一个成员是一个位置大小的数组,这就是柔性数组。1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34#include

#include

typedef struct st_type

{

int i;

int a[];//柔性数组成员

}type_a;

int main()

{

type_a* p = (type_a*)malloc(sizeof(type_a) + sizeof(int) * 10);//为结构体分配内存空间

p->i = 0;

for(int i = 0 ;i < 10; i++)

{

p->a[i] = 0;

}

for(int i = 0; i < 10; i++)

{

printf("%dn", p->a[i]);

}

free(p);

}

0

0

0

0

0

0

0

0

0

0

在以上这个例子中我们使用了柔性数组,在使用柔性数组的时候我们要对结构体进行动态内存分配,并且分配的空间要大于结构体除柔性数组外的空间。

柔性数组的特点:

1、结构体中柔性数组前面必须至少一个其他成员。

2、sizeof测量结构体大小不包括柔性数组的大小。

3包含柔性数组的结构体用malloc进行内存动态分配,并且分配的内存大于结构体大小以适应 预期大小。

c语言 12大于12么,【C语言】第十二章相关推荐

  1. C语言程序设计现代方法(第二版)十二章课后练习题部分答案

    作为C语言初学者,以下内容为自己学习时所记,内容如有错误之处欢迎指出,非常感谢. 在此本人想致谢50no ,在此书的前面章节学习过程中曾多次参考50no 写的课后编程题答案 . 12.1 (a) 14 ...

  2. C语言程序设计现代方法(第二版)十二章编程题答案

    作为一名C语言初学者,以下答案为随手练习笔记,均已通过编译器实现书上功能,如有错误之处欢迎指出. 1. (a) # include <cstdio> # include <iostr ...

  3. C语言谭浩强第三版第十二章例题及课后题:位运算

    eg12.1取一个整数a从右端开始的4~7位 0000...000000        0 1111...111111       ~0  1111...110000       ~0<< ...

  4. R语言实战笔记--第十二章 重抽样(置换检验)与自助法

    R语言实战笔记–第十二章 重抽样(置换检验)与自助法 标签(空格分隔): R语言 重抽样 自助法 置换检验 置换检验 双样本均值检验的时候,假设检验的方法就是,检查正态性.独立性.方差齐性,分别对应的 ...

  5. 谭浩强c语言不讲位运算呢,谭浩强C语言教程第十二章-位运算.doc

    谭浩强C语言教程第十二章-位运算 12位运算1 12.1位运算符C语言提供了六种位运算符:1 12.1.1按位与运算1 12.1.2按位或运算2 12.1.3按位异或运算2 12.1.4求反运算3 1 ...

  6. 《汇编语言》王爽(第四版) 第十二章 实验12

    文章目录 前言 一.思路分析 1.安装 2.设置中断向量 3.do0程序 4.测试 5.优化 二.最终成果 1.完整代码 2.效果图 总结 前言 本文是王爽老师<汇编语言>(第四版) 第十 ...

  7. c语言压缩文本文件北京理工大学,北京理工大学C语言程序设计第十二章文件.ppt...

    北京理工大学C语言程序设计第十二章文件 2000年1月25日 北京理工大学 / 第十二章 文件 第一节 文件概述 第二节 文件的处理 第三节 文件的顺序读写操作 第四节 文件的随机读写操作 第五节 文 ...

  8. 读书笔记-《ON JAVA 中文版》-摘要12[第十二章 集合]

    文章目录 第十二章 集合 1. 泛型和类型安全的集合 2. 基本概念 3. 添加元素组 4. 集合的打印 5. 列表List 6. 迭代器Iterators 6.1 Iterators 6.2 Lis ...

  9. 谭浩强c语言不讲位运算呢,谭浩强c语言教程_第十二章-位运算谭浩强c语言教程_第十二章-位运算.doc...

    12位运算1 12.1位运算符C语言提供了六种位运算符:1 12.1.1按位与运算1 12.1.2按位或运算2 12.1.3按位异或运算2 12.1.4求反运算3 12.1.5左移运算3 12.1.6 ...

  10. 12星座的出生年月日性格_十二个星座的出生年月日

    星座与天道的十二个课程 占星术是一门让人类了解自身处境的学问,自古以来占星术一直用这种方法帮助人类,占星术的十二个星座,透露了天道的十二个课程,这有点象中国易经的六十四卦一样,都是在告诉人类,处什麼样 ...

最新文章

  1. 高职信息安全比赛攻防思路_30.LNGZ2020-30:2020年辽宁省职业院校技能大赛(高职组)“信息安全管理与评估”赛项规程...
  2. Linux系统版 lscpu
  3. 纯数学教程 Page 325 例LXVIII (13)
  4. 黑客与网管的30天较量
  5. python PyQt5 QSplitter类(可拉伸区域分隔器)
  6. nginx 文件说明(非文件配置说明)
  7. Linux 下挂载新硬盘方法
  8. 工作388-jq返回实例
  9. 剑指Offer - 面试题3. 数组中重复的数字(哈希)
  10. qt程序运行时绘图出现错误
  11. volatile 用处
  12. ncl 多个单一时间文件合并成一个nc文件_iOS逆向--MachoO文件
  13. 计算机网络按照工作模式可分为什么和什么,计算机网络的分类有哪些?计算机网络工作模式...
  14. 圆柱体积怎么算立方公式_圆柱的体积换算立方怎么算
  15. AndroidStudio配置夜神模拟器
  16. 关于iPhone 5的适配
  17. 乐嘉性格色彩-4色特性,学习感悟
  18. 时间序列平稳性检验—R语言KPSS检验
  19. Cannot get a STRING value from a NUMERIC cell最新解决方法
  20. 厦门大学计算机英语考试,【图片】一战厦大计算机上岸,经验帖。慢更【考研吧】_百度贴吧...

热门文章

  1. Spring boot配置文件加载位置
  2. SQLserver多条件查询
  3. php学历低,学历低学起php来难不难
  4. php留言板代码容易出错,制作PHP+MYSQL留言板代码出错。
  5. jcifs java_Java 使用JCIFS访问网络文件共享的工具类
  6. 二维稳态热传导 代码实现_博世壁挂炉发生故障代码及处理办法
  7. wordpress使用的插件记录
  8. RocketMQ入门到入土(一)新手也能看懂的原理和实战!
  9. 我在实际工作中用的最多的 git 命令,全在这里了,使用简单!
  10. 妈妈再也不担心我面试被 Redis 问得脸都绿了