前提

看视频得来的内容,只知道不止4个区,但主要是这4个区。

四区

静态区
用于存放所有的全局变量和静态变量。
int a=; //静态区
int main(){
static int b=; //静态区
return ;
}
代码区
就是存放程序的执行代码,运行时该区内容不可修改。
栈区
用于存放所有的局部auto变量(非static,非register等),先进后出原则!
需要说明的是,栈区通常比较小,以KB为单位!所以存在overstack的可能性!--也就是俗称的爆栈~
int max(int &a, int &b){ //a、b均在栈区。C语言中函数的形参入栈顺序是从右往左!
return a>b?a:b;
}
int main(){
int a=;//栈区
}
堆区
空间较大,需要手动分配及释放,如果忘记释放,存在溢出可能。
堆空间比较自由,没有进出的顺序。
C语言中使用void *p = malloc(size)分配空间,使用free(p)释放空间。
需要注意的是,分配后,空间会有残余内容,需要手动清理。 int *p = (int*) malloc( sizeof(int) * ); //分配了40个字节
free(p); //释放了分配的空间。

以上,面试的时候通常会问到什么时候会栈溢出,根据栈区的定义,只要局部变量的总长度超出栈长度即可。

例如,

int arr[**]={}; //栈空间,超长
while(){
int a=; //栈空间,无限压入
}
//或者,递归次数太多!

注意,malloc分配的空间并未提供初始化,所以需要手动初始化。

memset(p, initVal, len); //将p地址开始的len长度范围内的空间的值初始化为initVal。

C中提供了另外两个函数来操作堆空间。

void *calloc(size_t _NumOfElements, size_t _SizeOfElement); //需要提供元素类型的数量及长度

void *realloc(void *p, size_t _NewSize); //重新分配空间。需要提供原空间地址以及新空间的长度。注意,如果原地址没有足够的连续空间,那会复制到新空间,并释放原空间。

realloc会返回新的空间地址(或者和原地址相同),或者返回NULL(0)--如果堆中任何地方都没有足够的空间!

另外,其超出原空间长度的部分,内容不会初始化。

测试代码

#include <memory.h>
#include <stdio.h>
#include <stdlib.h> /**
* @brief test_heap 验证C函数形参是从右往左压入栈中
* @param a
* @param b
*/
void test_heap(int a, int b) {
printf("first parameter's addr is [%d],\nsecond parameter's addr is [%d]\n", &a, &b);
} int main() {
printf("sizeof(int) = %d\n", sizeof(int)); int *pi = (int *)malloc(sizeof(int) * ); //手动分配堆内存
for (int i = ; i != ; ++i) { //注意,这里的10的单位是int!
printf("pi[%d] = %d, addr = %d\n", i, pi[i], &pi[i]);
} //手动清零
memset(pi, , * sizeof(int)); //注意,这里的长度单位是字节
for (int i = ; i != ; ++i) { //注意,这里的10的单位是int!
printf("pi[%d] = %d, addr = %d\n", i, pi[i], &pi[i]);
} free(pi); //
pi = (int *)calloc(, sizeof(int)); // calloc
for (int i = ; i != ; ++i) { //注意,这里的10的单位是int!
printf("pi[%d] = %d, addr = %d\n", i, pi[i], &pi[i]);
}
// free(pi); //note this and realloc printf("after free, pi = %d\n", pi);
int *pi2 = (int *)realloc(pi, ); // 20是比原来短了。注意,如果使用pi,则之前不能free(pi)。
printf("after realloc, pi = %d\n", pi);
printf("after realloc, pi2 = %d\n", pi2); //如果整个堆当中都没有任何一处的内存能够满足realloc的需求。则此次分配失败,返回值为NULL
for (int i = ; i != ; ++i) { //注意,这里的10的单位是int!
printf("pi[%d] = %d, addr = %d\n", i, pi2[i], &pi2[i]);
}
free(pi2);
free(pi); // free(pi2) is ok //
test_heap(, ); return ;
}

C的内存四大区的更多相关文章

  1. 面向过程—面向对象(C++的封装,this)_内存四区_变量生命周期

    1.面向对象主要涉及  构造函数.析构函数.虚函数.继承.多态等. 2.对各种支持 的底层实现机制 c语言中,数据 和 处理数据的操作(函数) 是分开来声明,即语言本身并没有支持 “数据和函数”的关联 ...

  2. C语言内存四区的学习总结(三)---- 栈区

    接上篇内存四区的堆区的总结,下面做一些栈区的相关总结. 一.栈区的分析: 就下面测试程序 #include "stdio.h" #include "string.h&qu ...

  3. C语言内存四区的学习总结(二)---- 堆区

    接上篇,内存四区的分析-静态区,下面来说明一下堆区总结. 堆区分析: 堆区(heap):一般由程序员分配释放(动态内存申请与释放),若程序员不释放,程序结束时可能由操作系统回 就下面的程序: #inc ...

  4. C语言内存四区的学习总结(一)---- 静态区

    最近重新学习C语言相关知识,重新提到内存四区的概念,那么在之前的学习的基础上,在这儿做一个简单的总结与分享. 一.内存四区建立的流程 可以简单直观的查看下面的这个图片,直接的说明我们的程序在内存中是如 ...

  5. C语言进阶之路(一)----C语言的内存四区模型

    内存四区模型:操作系统给C/C++编写的程序分配内存,通常将分配的内存划分为以下四个区域:1.栈区:存放局部变量,用完由操作系统自动释放2.堆区:动态分配给程序的内存区域,由程序员手动释放3.数据区: ...

  6. C++变量存储类别和内存四区

    变量存储类别 变量声明/定义的一般形式: 存储类别 数据类型 变量名 存储类别指的是数据在内存中存储的方法.存储方法分为静态存储和动态存储两大类.标准C语言为变量.常量和函数定义了4种存储类型:ext ...

  7. C语言之内存四区模型和函数调用模型

      内存四区模型 流程说明1.操作系统把物理硬盘代码load到内存2.操作系统把c代码分成四个区3.操作系统找到main函数入口执行 1.内存四区: 一个由c/C++编译的程序占用的内存分为以下几个部 ...

  8. 11、C内存四区模型

    转载于:https://blog.csdn.net/wu5215080/article/details/38899259 内存四区模型 图1.内存四区模型流程说明1.操作系统把物理硬盘代码load到内 ...

  9. C语言的内存四区模型和函数调用模型

    首先是操作系统将代码程序加载到内存中 然后将内存分为4个区 栈区,程序的局部变量区,函数传递的参数,由编译器自动进行内存资源的释放. 堆区,动态内存申请,如果不手动释放内存,则这块内存不会进行析构. ...

随机推荐

  1. 使用 powerdesigner 将数据库表结构逆向工程生成对应的word文档

    本机系统win10 + mysql 5.7.17 + powerDesigner 16.5 + mysql-connector-odbc-5.3.9-winx32.msi 1 使用 PowerDesi ...

  2. Hadoop本地库介绍及相关问题解决方法汇总

    1.hadoop本地库的作用是什么?2.哪两个压缩编码器必须使用hadoop本地库才能运行?3.hadoop的使用方法?4.hadoop本地库与系统版本不一致会引起什么错误?5.$ export HA ...

  3. OOM问题定位方法

    1. 背景 线上内存OOM问题是最难定位的问题,最常见的原因: (1)本身资源不够 (2)申请的太多 (3)资源耗尽 某服务器上部署了Java服务,出现OutOfMemoryError,请问有可能是什 ...

  4. android笔记---AndroidManifest.xml

    <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="ht ...

  5. compiled inline cache

    http://cr.openjdk.java.net/~jrose/pres/200910-VMIL.pdf https://wiki.openjdk.java.net/display/HotSpot ...

  6. C++ 顺序容器原理

    容器分为顺序容器与关联容器,顺序容器也称为序列式容器.序列式容器按元素插入的顺序存储元素,这些元素可以进行排序,但未必是有序的.C++本身内置了一个序列式容器array(数组),STL另外提供了vec ...

  7. C++内联函数详解

    1.函数调用原理 "编译过程的最终产品是可执行程序--由一组机器语言指令组成.运行程序时,操作系统将这些指令载入计算机内存中,因此每条指令都有特定的内存地址.计算机随后将逐步执行这些指令.有 ...

  8. 使用TortoiseGit操作分支的创建与合并功能集合

    使用TortoiseGit操作分支的创建与合并 本文在介绍了软件安装和设置后, 写了TortoiseGit 常用的一些功能, 包括: 创建新库 添加文件及文件夹 创建分支 看分支情况及修改log 比较 ...

  9. Java-web-j2e学习建议路线【转】

    首先要明白Java体系设计到得三个方面:J2SE,J2EE,J2ME(KJAVA).J2SE,Java 2 Platform Standard Edition,我们经常说到的JDK,就主要指的这个,它 ...

  10. 检测SqlServer数据库是否能连接的小技巧

    有时候可能需要检测下某台机器的服务是不是起来了,或者某台机器的某个库是不是能被连接又不能打开ssms也不想登陆服务器的话就可以用这个方法. 1.在桌面上右键创建个文本,然后改后缀名为udl以后保存(1 ...