博客
关于我
C语言内存
阅读量:685 次
发布时间:2019-03-17

本文共 3113 字,大约阅读时间需要 10 分钟。

1. 程序中的内存从哪里来?

对于一个正在运行的程序来说,内存是其赖以运行的基础。内存是程序存储和操作的核心资源,虽然你可能很难看到内存本身,但内存的存在让程序能够稳定地运行。

1.1 程序执行需要内存支持

内存是程序的起点,程序是被放置在内存中运行的。程序运行时需要内存来存储一些临时变量和操作结果。此外,内存是计算机的核心资源之一,每个进程都有自己的内存空间。

1.2 内存管理由操作系统完成

内存管理最终是由操作系统负责的。内存在物理上是一个硬件器件,由硬件系统提供,但操作系统通过自己的管理机制统一控制内存的分配和使用。你需要通过操作系统获取内存权限。

内存可以分为三种主要类型:

  • 栈(Stack):运行时自动分配和回收,方便且简单。栈中的内存反复使用,分配时保留原来的值。
  • 堆(Heap):由操作系统内置管理器管理,灵活且大块,堆内存可以按需申请和释放,但必须手动管理(使用mallocfree)。
  • 数据区(.data):简单来说就是全局变量,包括显式初始化和未显式初始化的全局变量。

栈的详解

栈分配内存的优点包括:

  • 自动管理:栈内存由编译器和运行时环境自动处理,无需手动干预。
  • 反复使用:栈内存可以被多次使用,很容易反复分配。
  • 临时性:栈变量的生命周期仅在函数执行过程中,函数结束后栈内存就会被释放。

栈的局限也很明显:

  • 由于栈内存有限,函数无限分配栈内存会导致栈溢出,程序崩溃。
  • 栈变量不能被函数返回,因为它们随着函数执行结束而被销毁。

堆内存详解

堆内存管理灵活且大块,适合多种应用场景:

  • 操作系统管理:操作系统的堆管理器负责内存的分配和释放。
  • 手动申请和释放:程序可以通过malloc申请内存和free释放内存。
  • 内存的脏性:堆内存使用后如果没有及时释放,会导致内存泄漏。
  • 临时性:堆内存只能在mallocfree结束后使用,否则不可预测。

堆内存的使用范例

  • 使用malloc申请内存:int *p = (int *)malloc(1000 * sizeof(int));
  • 正确使用前必须检验:if (p == NULL) { /* 处理内存分配失败情况 */ }
  • 使用完成后必须释放:free(p);
  • 不要在释放前对指针重新赋值,否则会导致内存泄漏。

malloc的细节

  • malloc(0)通常返回一块16字节的内存,具体实现取决于库。
  • malloc默认最小分配单元是16字节。
  • 远远大的块如20字节的内存会在检查到被破坏时引发段错误。

2. 堆内存详解

3. 栈溢出的实例

void stack_overflow(void) {
int a[100000000] = {0};
a[100000000 - 1] = 12;
}
int main(void) {
stack_overflow();
}
  • 当栈内分配的数组大小超过系统栈的容量时,程序会报错:Segmentation fault (core dumped)
  • 栈溢出的本质原因是对 ard的栈内存请求超过了栈的容量。

4. 堆内存详解

5. 栈溢出的实例

void stack_overflow(void) {
int a[100000000] = {0};
a[100000000 - 1] = 12;
}
int main(void) {
stack_overflow();
}
  • 当栈内分配的数组大小超过系统栈的容量时,程序会报错:Segmentation fault (core dumped)
  • 栈溢出的本质原因是对 arid的栈内存请求超过了栈的容量。

6. 堆内存详解

7. 堆内存的使用范例

  • 使用malloc申请内存:int *p = (int *)malloc(1000 * sizeof(int));
  • 正确使用前必须检验:if (p == NULL) { /* 处理内存分配失败情况 */ }
  • 使用完成后必须释放:free(p);
  • 不要在释放前对指针重新赋值,否则会导致内存泄漏。

8. malloc的细节

  • malloc(0)通常返回一块16字节的内存,具体实现取决于库。
  • malloc默认最小分配单元是16字节。
  • 远远大的块如20字节的内存会在检查到被破坏时引发段错误。

9. 堆内存使用范例

  • 使用malloc申请内存:int *p = (int *)malloc(1000 * sizeof(int));
  • 正确使用前必须检验:if (p == NULL) { /* 处理内存分配失败情况 */ }
  • 使用完成后必须释放:free(p);
  • 不要在释放前对指针重新赋值,否则会导致内存泄漏。

10. malloc的细节

  • malloc(0)通常返回一块16字节的内存,具体实现取决于库。
  • malloc默认最小分配单元是16字节。
  • 远远大的块如20字节的内存会在检查到被破坏时引发段错误。

11. 栈溢出的实例

void stack_overflow(void) {
int a[100000000] = {0};
a[100000000 - 1] = 12;
}
int main(void) {
stack_overflow();
}
  • 当栈内分配的数组大小超过系统栈的容量时,程序会报错:Segmentation fault (core dumped)
  • 栈溢出的本质原因是对 arid的栈内存请求超过了栈的容量。

12. 堆内存详解

13. 堆内存的使用范例

  • 使用malloc申请内存:int *p = (int *)malloc(1000 * sizeof(int));
  • 正确使用前必须检验:if (p == NULL) { /* 处理内存分配失败情况 */ }
  • 使用完成后必须释放:free(p);
  • 不要在释放前对指针重新赋值,否则会导致内存泄漏。

14. malloc的细节

  • malloc(0)通常返回一块16字节的内存,具体实现取决于库。
  • malloc默认最小分配单元是16字节。
  • 远远大的块如20字节的内存会在检查到被破坏时引发段错误。

15. 堆内存使用范例

  • 使用malloc申请内存:int *p = (int *)malloc(1000 * sizeof(int));
  • 正确使用前必须检验:if (p == NULL) { /* 处理内存分配失败情况 */ }
  • 使用完成后必须释放:free(p);
  • 不要在释放前对指针重新赋值,否则会导致内存泄漏。

16. malloc的细节

  • malloc(0)通常返回一块16字节的内存,具体实现取决于库。
  • malloc默认最小分配单元是16字节。
  • 远远大的块如20字节的内存会在检查到被破坏时引发段错误。

17. 堆内存详解

18. 堆内存的使用范例

  • 使用malloc申请内存:int *p = (int *)malloc(1000 * sizeof(int));
  • 正确使用前必须检验:if (p == NULL) { /* 处理内存分配失败情况 */ }
  • 使用完成后必须释放:free(p);
  • 不要在释放前对指针重新赋值,否则会导致内存泄漏。

19. malloc的细节

  • malloc(0)通常返回一块16字节的内存,具体实现取决于库。
  • malloc默认最小分配单元是16字节。
  • 远远大的块如20字节的内存会在检查到被破坏时引发段错误。

20. 堆内存详解

通过以上内容可以看出,无论是栈、堆还是数据区,内存都是程序运行不可或缺的一部分。理解这些内存类型及其管理方式,是开发程序的基础技能。

转载地址:http://xyvhz.baihongyu.com/

你可能感兴趣的文章
NumPy中的精度:比较数字时的问题
查看>>
numpy判断对应位置是否相等,all、any的使用
查看>>
Numpy多项式.Polynomial.fit()给出的系数与多项式.Polyfit()不同
查看>>
Numpy如何使用np.umprod重写range函数中i的python
查看>>
numpy学习笔记3-array切片
查看>>
numpy数组替换其中的值(如1替换为255)
查看>>
numpy数组索引-ChatGPT4o作答
查看>>
numpy最大值和最大值索引
查看>>
NUMPY矢量化np.prod不能构造具有超过32个操作数的ufunc
查看>>
Numpy矩阵与通用函数
查看>>
numpy绘制热力图
查看>>
numpy转PIL 报错TypeError: Cannot handle this data type
查看>>
Numpy闯关100题,我闯了95关,你呢?
查看>>