iOS数据存储类型 及 堆(heap)和栈(stack)

一般认为在c中分为这几个存储区:

1栈 --  由编译器自动分配释放。
2堆 --  一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。
3全局区(静态存储区)-- 全局变量和静态变量的存储是放在一块区域
,程序退出后自动释放 。全局区又分为全局初始化区和全局未初始化区。初始化的全局变量和静态变量存放在全局初始化区,未初始化的全局变量和未初始化的静态变量存放在相邻的另一块区域。


4常量区
-- 专门放数字/字符常量的地方, 程序退出后自动释放 。

在函数体中定义的自动变量通常是在栈上

用malloc,
calloc, realloc等分配内存的函数分配得到的就是在堆上

加了static修饰符后不管在哪里都存放在全局区(静态存储区)。

在所有函数体外定义的是全局变量,存储在全局区(静态存储区),在整个C程序所有源文件中通过extern声明后都可用。

在所有函数体外定义的static全局变量存储在全局区(静态存储区),只在该文件中有效,不能extern声明到别的文件用。

在函数体内定义的static静态变量存储在全局区(静态存储区),表示只在该函数体内有效,但是其生命周期却变为和整个程序同生同死。

另外,函数中的"adgfdf"这样的字符串存放在常量区

代码: 
int a = 0; //全局初始化区 
char *p1; //全局未初始化区 
main() 

int b; //栈 
char s[] = "abc"; //栈 
char *p2; //栈 
char *p3 = "123456";  //123456\0在常量区,p3在栈上。 
static int c = 0; //全局(静态)初始化区 
p1 = (char *)malloc(10);   //分配得来的10 字节的区域就在堆区。 
p2 = (char *)malloc(20);  //分配得来的 20字节的区域就在堆区。 
strcpy(p1, "123456");   //123456\0放在常量区,编译器可能会将它与p3所指向的"123456"优化成一块。 
}

函数调用时会在栈上有一系列的保留现场及传递参数的操作。 栈的空间大小有限定,VC的缺省是2M。栈不够用的情况一般是程序中分配了大量数组和递归函数层次太 深。有一点必须知道,当一个函数调用完返回后它会释放该函数中所有的栈空间。栈是由编译器自动管理的,不用你操心。

堆是动态分配内存的,并且你可以分配使用很大的内存。但是用不好会产生内存泄漏。 并且频繁地malloc和free会产生内存碎片(有点类似磁盘碎片),因为c分配动态内存时是寻找匹配的内存的。而使用栈则不会产生碎片。

一般大家说的堆栈和栈是一样的,就是栈(stack),而说堆时才是堆heap。在栈上存取数据比通过指针在堆上存取数据快些。 栈是先入后出的,一般是由高地址向低地址生长。

堆(heap)和栈(stack)是C/C++编程不可避免会碰到的两个基本概念。

栈是机器系统提供的数据结构,而堆则是C/C++函数库提供的。 
具体地说,现代计算机(串行执行机制),都直接在代码底层支持栈的数据结构。这体现在,有专门的寄存器指向栈所在的地址,有专门的机器指令完成数据入栈出栈的操作。 
这种机制的特点是效率高,支持的数据有限,一般是整数,指针,浮点数等系统直接支持的数据类型,并不直接支持其他的数据结构。因为栈的这种特点,对栈的使用在程序中是非常频繁的。

C/C++中的自动变量是直接利用栈的例子,这也就是为什么当函数返回时,该函数的自动变量自动失效的原因。

和栈不同,堆的数据结构并不是由系统(无论是机器系统还是操作系统)支持的,而是由函数库提供的。 
基本的malloc/realloc/free函数维护了一套内部的堆数据结构。当程序使用这些函数去获得新的内存空间时,这套函数首先试图从内部堆中寻找可用的内存空间,如果没有可以使用的内存空间,则试图利用系统调用来动态增加程序数据段的内存大小,新分配得到的空间首先被组织进内部堆中去,然后再以适当的形式返回给调用者。当程序释放分配的内存空间时,这片内存空间被返回内部堆结构中,可能会被适当的处理(比如和其他空闲空间合并成更大的空闲空间),以更适合下一次内存分配申请。这套复杂的分配机制实际上相当于一个内存分配的缓冲池(Cache),使用这套机制有如下若干原因:

1. 系统调用可能不支持任意大小的内存分配。有些系统的系统调用只支持固定大小及其倍数的内存请求(按页分配);这样的话对于大量的小内存分类来说会造成浪费。

2. 系统调用申请内存可能是代价昂贵的。系统调用可能涉及用户态和核心态的转换。

3. 没有管理的内存分配在大量复杂内存的分配释放操作下很容易造成内存碎片。

堆和栈的对比

从以上知识可知,栈是系统提供的功能,特点是快速高效,缺点是有限制,数据不灵活;而栈是函数库提供的功能,特点是灵活方便,数据适应面广泛,但是效率有一定降低。

栈是系统数据结构,对于进程/线程是唯一的;堆是函数库内部数据结构,不一定唯一。不同堆分配的内存无法互相操作。栈空间 
分静态分配和动态分配两种。静态分配是编译器完成的,比如自动变量(auto)的分配。动态分配由alloca函数完成。栈的动态分配无需释放(是自动的),也就没有释放函数。为可移植的程序起见,栈的 
动态分配操作是不被鼓励的!

堆空间的分配总是动态的,虽然程序结束时所有的数据空间都会被释放回系统,但是精确的申请内存/释放内存匹配是良好程序的基本要素。

iOS数据存储类型 及 堆(heap)和栈(stack)的更多相关文章

  1. [转]JVM 内存初学 (堆(heap)、栈(stack)和方法区(method) )

    这两天看了一下深入浅出JVM这本书,推荐给高级的java程序员去看,对你了解JAVA的底层和运行机制有比较大的帮助.废话不想讲了.入主题: 先了解具体的概念:JAVA的JVM的内存可分为3个区:堆(h ...

  2. 堆heap和栈Stack(百科)

    堆heap和栈Stack 在计算机领域,堆栈是一个不容忽视的概念,堆栈是两种数据结构.堆栈都是一种数据项按序排列的数据结构,只能在一端(称为栈顶(top))对数据项进行插入和删除.在单片机应用中,堆栈 ...

  3. JVM 内存初学 堆(heap)、栈(stack)和方法区(method)

    这两天看了一下深入浅出JVM这本书,推荐给高级的java程序员去看,对你了解JAVA的底层和运行机制有比较大的帮助.废话不想讲了.入主题:先了解具体的概念:JAVA的JVM的内存可分为3个区:堆(he ...

  4. 转:JVM 内存初学 (堆(heap)、栈(stack)和方法区(method) )

    原文地址:JVM 内存初学 (堆(heap).栈(stack)和方法区(method) ) 博主推荐 深入浅出JVM 这本书 先了解具体的概念:JAVA的JVM的内存可分为3个区:堆(heap).栈( ...

  5. java虚拟机知识和 内存 堆(heap)、栈(stack)和方法区(method)

    1.虚拟机实例 每个java程序都运行在自己的java虚拟机实例中,运行三个java程序就会得到三个虚拟机实例 守护线程(虚拟机自己使用,比如说执行垃圾收集任务的线程) 非守护线程(java初试线程, ...

  6. JVM 内存初学 (堆(heap)、栈(stack)和方法区(method) )(转载)

    想想面试的时候很多会问jvm这方面的问题虽然还是菜鸟不太能用到现在但是还是了解一下, 找资料的时候看见个大佬写的很好转载到这方便以后自己复习和给大佬做宣传 以下为大佬的博客原文: 这两天看了一下深入浅 ...

  7. java面试之----堆(heap)、栈(stack)和方法区(method)

    JAVA的JVM的内存可分为3个区:堆(heap).栈(stack)和方法区(method)也叫静态存储区. 堆区: 1.存储的全部是对象,每个对象都包含一个与之对应的class的信息.(class的 ...

  8. JVM内存模型——堆(heap)、栈(stack)和方法区(method)

      JAVA的JVM的内存可分为3个区:堆(heap).栈(stack)和方法区(method) 堆区:堆内存用于存放由new创建的对象和数组.堆是JVM管理的内存中最大的一块,堆被所有线程共享,目的 ...

  9. JVM 内存 (堆(heap)、栈(stack)和方法区(method) )

    JVM 内存初学 (堆(heap).栈(stack)和方法区(method) ) 堆区: 1.存储的全部是对象,每个对象都包含一个与之对应的class的信息.(class的目的是得到操作指令)2.jv ...

随机推荐

  1. spring框架笔记

    Spring实现依赖注入的两种方式: 1.构造方法注入 2.set方法注入,p标签注入 Spring中事务的两种实现方式: 编程式事务管理 声明式事务管理(推荐) Spring增强类型: Before ...

  2. Bzoj1498&1416: [NOI2006]神奇的口袋

    什么鬼双倍经验题??? Sol 考虑在第\(k\)次摸到\(y\)的概率 如果上次摸到\(y\),目前有\(sum\)个球,\(y\)有\(a[y]\)个,那么概率就是\(\frac{a[y]+d}{ ...

  3. 纯CSS实现立方体旋转

    下面为通过CSS动画实现的立方体旋转,可以改变CSS代码中关键帧定义(@keyframes)来改变立方体的旋转方式 HTML部分: <body class="body"> ...

  4. 申请微信小程序步骤

    一.注册 注册网址:https://mp.weixin.qq.com/ 选择账号类型:选择 小程序 注册账号 填写邮箱密码并激活:未注册过公众平台.开放平台.企业号.未绑定个人号的邮箱. 填写主体信息 ...

  5. Java 之变量和常量(2)

    Java中的关键字: Java 语言中有一些具有特殊用途的词被称为关键字.关键字对 Java 的编译器有着特殊的意义,在程序中应用时一定要慎重哦!! Java 中常用关键字: 问:这么多,记不住啊.. ...

  6. 一、flex布局教程:语法篇

    本文转自阮一峰大师的教程,此处做记录,方面后面自己学习使用~   布局的传统解决方案,基于盒状模型,依赖 display属性 + position属性 + float属性.它对于那些特殊布局非常不方便 ...

  7. Mysql存储Emoji表情[为何utf8不能存储以及如何使Mysql能够存储Emoji表情]

    https://segmentfault.com/a/1190000008533577

  8. androidUI异步消息

    private Handler handler = new Handler(){ public void handleMessage(android.os.Message msg) { switch ...

  9. mysql 免安装版安装(window7)

    初次使用mysql免安装版步骤: 1.设置环境变量,将mysql 加压文件路径添加到环境变量path中(作用是不用每次都切换路径) 控制面板>系统和安全>系统>高级系统设置 2.安装 ...

  10. Mac os下profile设置

    Mac os环境下home目录下是没有profile文件的开启终端后,读取的是/etc/profile文件因为个人喜欢使用ll命令,mac默认并没有这个命令,所以使用如下方法设置别名 cp -rp / ...