首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

编码篇-iOS程序中的内存分配 栈区堆区全局区等相关知识

前言 在计算机的系统中,运行的应用程序中的数据都是保存在内存中,不同类型的数据,保存的内存区域不同。内存区域大致可以分为:栈区、堆区、全局区(静态区)、文字常量区、程序代码区。...【顺序随意】 堆空间的分配总是动态的虽然程序结束时所有的数据空间都会被释放回系统, 但是精确的申请内存与释放是优质程序开发者必备的素质。...2.当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点, 然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序。...文字常量区 存放常量字符串,程序结束后由系统释放 五.程序代码区 存放函数的二进制代码 补充说明 栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行...当创建一个NSCFConstantString对象时,会检测这个字符串内容是否已经存在,如果存在,则直接将地址赋值给变量;不存在的话,则创建新地址,再赋值。

1.6K20
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    栈区和堆区内存分配区别

    程序结束后由系统释放 4、文字常量区 常量字符串就是放在这里的。 程序结束后由系统释放 5、程序代码区 存放函数体的二进制代码。 先看一个例子....char c; //栈上分配 char *p = new char[3]; //堆上分配,将地址赋给了p; 在 编译器遇到第一条指令时,计算其大小,然后去查找当前栈的空间是大于所需分配的空间大小,如果这时栈内空间大于所申请的空间...,这个时候,大家已经清楚了,p中现在存放的是在堆中申请的字符数组的首地址,也就是在堆中申请的数组的地址现在被赋给了在栈上申请的指针变量p.为了更加形象的说明问题,请看下图: 从上图可以看出,我们在堆上动态分配的数组的首地址存入了指针...堆和栈中的存储内容 栈: 在函数调用时,第一个进栈的是主函数中后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈的,然后是函数中的局部变量...是在编译时就确定的; 但是,在以后的存取中,在栈上的数组比指针所指向的字符串(例如堆)快。

    1.2K30

    java堆、栈、堆栈,常量池的区别,史上最全总结

    栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方。与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆。 2....常量池的好处是为了避免频繁的创建和销毁对象而影响系统性能,其实现了对象的共享。 例如字符串常量池,在编译阶段就把所有的字符串文字放到一个常量池中。...(2) 然后在堆中(不是常量池)创建一个指定的对象,并让str引用指向该对象。 (3) 在常量池中查找是否存在内容为"abc"字符串对象。...而对于String str = new String("abc");的代码,则一概在堆中创建新对象,而不管其字符串值是否相等,是否有必要创建新对象,从而加重了程序的负担。...堆:首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序,另外,对于大多数系统

    3.6K30

    详解栈区、堆区、全局区、文字常量区、程序代码区

    一个由C/C++编译的程序占用的内存分为以下几个部分 栈区(stack):由编译器自动分配、释放,存放函数的参数值、局部变量的值等。其操作方式类似于数据结构中的栈。...初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 文字常量区:常量字符串就是放在这里的。程序结束后由系统释放 程序代码区:存放函数体的二进制代码。...堆:首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序,另外,对于大多数系统...堆和栈中的存储内容 栈:在函数调用时,第一个进栈的是主函数中后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈的,然后是函数中的局部变量...是在编译时就确定的; 但是,在以后的存取中,在栈上的数组比指针所指向的字符串(例如堆)快。

    41610

    深入理解Java:String

    而JVM中的常量池在内存当中是以表的形式存在的, 对于String类型,有一张固定长度的CONSTANT_String_info表用来存储文字字符串值,注意:该表只存储文字字符串值,不存储符号引用。...要注意: 我们在使用诸如String str = "abc";的格式定义类时,总是想当然地认为,创建了String类的对象str。担心陷阱!对象可能并没有被创建!而可能只是指向一个先前已经创建的对象。...String的 intern()方法就是扩充常量池的 一个方法;当一个String实例str调用intern()方法时,Java 查找常量池中 是否有相同Unicode的字符串常量,如果有,则返回其的引用...,那么该方法返回表中已有字符串的地址,如果在表中没有相同值的字符串,则将自己的地址注册到表中”如果我把他说的这个全局的 String 表理解为常量池的话,他的最后一句话,”如果在表中没有相同值的字符串,...,也即重新申请一段更大的内存空间,然后将当前char数组拷贝到新的位置,因为重新分配内存并拷贝的开销比较大,所以每次重新申请内存空间都是采用申请大于当前需要的内存空间的方式,这里是2倍 【 StringBuffer

    35710

    《UNIX环境高级编程》第七章进程环境

    其中每个指针包含一个以null结束的C字符串的地址。 全局变量environ则包含了该指针数组的地址。...通常,正文段是可共享的。存放的有:代码、const全局变量、const静态变量、字符串字面值 数据段(已经初始化了):包含了程序中明确的赋初值的变量。例如:C程序任何函数之外的声明。...(这么一看有点像动态库) 在不同的系统中,程序可能使用不同的方法说明是否要使用共享库。...注意:环境表和环境字符串通常占用的是进程地址空间的顶部,所以它不能在向高地址扩展了;同时也不能移动在它之下的各栈帧,所以也不能向低地址方向扩展。 那么是如何实现上述操作的呢?...,须遵循下列三条规则: 1)任何一个进程都可以将一个软限制值更改为小于或等于其硬限制值 2)任何一个进程都可降低其硬限制值,但是它必须大于等于其软限制值。

    51010

    java堆、栈、堆栈,常量池的区别,史上最全总结

    栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方。与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆。 2....常量池的好处是为了避免频繁的创建和销毁对象而影响系统性能,其实现了对象的共享。 例如字符串常量池,在编译阶段就把所有的字符串文字放到一个常量池中。...(2) 然后在堆中(不是常量池)创建一个指定的对象,并让str引用指向该对象。 (3) 在常量池中查找是否存在内容为"abc"字符串对象。...而对于String str = new String("abc");的代码,则一概在堆中创建新对象,而不管其字符串值是否相等,是否有必要创建新对象,从而加重了程序的负担。...堆:首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序,另外,对于大多数系统

    5.4K74

    c认证初级

    在这个过程中,DHCP 客户机向 DHCP 服务器租用 IP 地址,DHCP 服务器只是暂时分配给客户机一个IP地址。只要租约到期,这个地址就会还给 DHCP 服务器,以供其他客户机使用。...如果 DHCP 客户机仍需要一个 IP 地址来完成工作,则可以再申请另外一个 IP 地址。所以,计算机获取的IP地址每次都可能变化,属于动态分配。...indexOf() 方法 返回指定字符串在字符串中首次出现的位置。匹配不到则返回-1。    ...lastIndexOf() 返回指定字符串值最后出现的位置,在一个字符串中的指定位置从后向前搜索。    ...它同时忽略 regexp 的 lastIndex 属性,并且总是从字符串的开始进行检索,这意味着它总是返回 stringObject 的第一个匹配的位置。

    1K20

    每天都在用String,你真的了解吗?

    Java程序中所有的字符串文字(例如"abc")都可以被看作是实现此类的实例 String 中包括用于检查各个字符串的方法,比如用于比较字符串,搜索字符串,提取子字符串以及创建具有翻译为大写或小写的所有字符的字符串的副本...3.1常量池的实现思想 字符串的分配,和其他的对象分配一样,耗费高昂的时间与空间代价,作为最基础的数据类型,大量频繁的创建字符串,极大程度地影响程序的性能 JVM为了提高性能和减少内存开销,在实例化字符串常量的时候进行了一些优化...,可以不用担心数据冲突进行共享 运行时实例创建的全局字符串常量池中有一个表,总是为池中每个唯一的字符串对象维护一个引用,这就意味着它们一直引用着字符串常量池中的对象,所以,在常量池中的这些字符串不会被垃圾收集器回收...= new String("abc") 这段代码会做两步操作,第一步在常量池中查找是否有"abc"对象,有则返回对应的引用实例,没有则创建对应的实例对象;在堆中new一个String("abc")对象...//如果起始地址小于0或者(起始地址+所比较对象长度)大于自身对象长度,返回假 if ((toffset value.length - pc)) {

    57320

    【嵌入式开发】C语言 指针数组 多维数组

    结果是可用的内存量, 如果可用内存大于n, 则可以赋值; -- 如果内存不足 : 内存不足, 将0作为地址返回, C语言中设定 0 不是有效的数据地址, 0地址的数据为NULL, 返回0表示发生了异常事件...c, 没有经过字符串复制; -- 区别 : 数组 - array 指向的地址不能改变, 单个字符可以修改; 指针 - c 指向字符串常量, 可以被修改指向其它地址, 修改字符串内容没有意义, 这样会在创建一个字符串常量...1, 然后出栈的时候要先减1 在取值; -- 出栈 : val = *--p, 这是标准的出栈操作, 现将指针减一, 然后取出指针指向的数据, 因为指针总是指向首地址, 如果我们想要取出某一段的值, 先要将指针指向首地址才可以...指针数组 指向指针的指针 示例 案例需求 :  -- 实现功能 : 在单个运算中处理长度不一的文本, 处理可变文本行数据;  -- 实际功能 : 从标准输入流中输入多个字符串, 每个字符串都使用指针指向字符串的首地址...; //空间分配的辅助偏移量 static char *allocp = allocbuf; /* * 分配内存 */ char *alloc(int n) { //判断剩余内存是否足够 if

    95260

    检查代码中的数据引用错误

    4、对于所有的通过指针或引用变量的引用,当前引用的内存单元是否分配?这就是所谓的“虚调用”错误。当指针的生命期大于所引用内存单元的生命期时,错误就会发生。...当C、C++或COBOL程序将某个记录读到内存中,并使用一个结构来引用它时,由于记录的物理表示与结构定义存在差异,这种情况下错误就可能发生7、在使用的计算机上,当内存分配的单元小于内存可寻址的单元大小时...例如,在某些条件下,定长的位串不必以字节边界为起点,但是地址又总是指向字节边界的。如果程序计算一个位串的地址,稍后又通过该地址引用这个位串,可能会指向错误的内存位置。...8、当使用指针或引用变量时,被引用的内存的属性是否与编译器所预期的一致?这种错误的一个例子是,当一个指向某个数据结构的C++指针,被赋值为另外的数据结构的地址。...10、如果字符串有索引,当对数组进行索引操作或下标引用,字符串的边界取值是否有“仅差一个”(off-by-one)的错误?11、对于面向对象的语言,是否所有的继承需求都在实现类中得到了满足?

    9210

    嘀~正则表达式快速上手指南(下篇)

    但是,数据并不总是直截了当的。常常会有意想不到的情况出现。例如,如果没有 From: 字段怎么办?脚本将报错并中断。在步骤2中可以避免这种情况。 ?...在步骤3A中,我们使用了if 语句来检查s_email的值是否为 None, 否则将抛出错误并中断脚本。...就像之前做的一样,我们在步骤3B中首先检查s_name 的值是否为None 。 然后,在将字符串分配给变量前,我们调用两次了 re 模块中的re.sub() 函数。...最终,将字符串分配给 sender_name并添加到字典中。 让我们检查下结果。 ? 非常棒!我们已经分离了邮箱地址和发件人姓名, 还将它们都添加到了字典中,接下来很快就能用上。...比如, 如果需要在字符串中查找 "a", "b", 或 "c" , 可以使用 [abc] 作为模式. 上文提到过的模式也适用。[\w\s] 用于查找字母、数字或空格。

    4K10

    char* 和char[]的差别

    4、文字常量区—常量字符串就是放在这里的。程序结束后由系统释放。...堆:首先应该知道操作系统有一个记录空暇内存地址的链表,当系统收到程序的申请时, 会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空暇结点链表中删除,并将 该结点的空间分配给程序,另外...2.5堆和栈中的存储内容 栈:在函数调用时,第一个进栈的是主函数中后的下一条指令(函数调用语句的下一条可运行语句)的 地址,然后是函数的各个參数,在大多数的C编译器中,參数是由右往左入栈的,然后是函数中的局部变...是在编译时就确定的; 可是,在以后的存取中,在栈上的数组比指针所指向的字符串(比如堆)快。...自我总结: char *c1 = “abc”;实际上先是在文字常量区分配了一块内存放”abc”,然后在栈上分配一地址给c1并指向 这块地址,然后改变常量”abc”自然会崩溃 然而char c2[] =

    1.2K30

    C#学习笔记 字符串和正则表达式

    字符串字面值 原始字符串 和很多语言相似,C#使用""来包括字符串字面值。字符串字面值可以是普通的字符串,也可以包含以\开头的转义字符。如果想让字符串字面值中包含\就必须写成\\这样的。...字符串 在C#中,字符串使用关键字string定义,该关键字其实是System.String类的缩写。string类有大量的方法,可以完成各种各样的事情。详情可参考MSDN。以下是一些基本操作。...例如,下面是判断字符串是否是有效的电子邮件地址的代码。...在字符串插入、追加、修改、删除等方面的效率很高,因为它是一个可变的字符串,所有的操作都会应用到字符串上,而不是创建一个新的字符串。因此在操作大量字符串的时候,应该使用它。...,可以用简单的操作来完成很多复杂的功能,例如判断一个字符串是否是一个合法的电子邮件地址,找出所有以M开头并且长度大于4的单词等等。

    59610

    十二张图带你了解 Redis 的数据结构和对象系统

    如果修改后, SDS 的长度将大于 1MB ,那么 Redis 会分配 1MB 的未使用空间。...当 SDS的 len 长度大于 1MB时,则只会再多分配 1MB的空间。 类似的,当 SDS 缩短其保存的字符串长度时,并不会立即释放多出来的字节,而是等待之后使用。...其每个元素都是 contents 数组的一个数组项,各个项在数组中按值的大小从小到大有序的排列,并且数组中不包含任何重复项。length 属性就是整数集合包含的元素数量。...embstr 只需一次内存分配,而且在同一块连续的内存中,更好的利用缓存带来的优势,但是 embstr 是只读的,不能进行修改,当一个 embstr 编码的字符串对象进行 append 操作时, redis...通过过期字典,Redis 可以直接判断一个键是否过期,首先查看该键是否存在于过期字典,如果存在,则比较该键的过期时间和当前服务器时间戳,如果大于,则该键过期,否则未过期。

    1K20

    Redis详解(四)------ redis的底层数据结构

    ②、杜绝缓冲区溢出 我们知道在 C 语言中使用 strcat  函数来进行两个字符串的拼接,一旦没有分配足够长度的内存空间,就会造成缓冲区溢出。...而对于 SDS 数据类型,在进行字符修改的时候,会首先根据记录的 len 属性检查内存空间是否满足需求,如果不满足,会进行相应的空间扩展,然后在进行修改操作,所以不会出现缓冲区溢出。...③、减少修改字符串的内存重新分配次数 C语言由于不记录字符串的长度,所以如果要修改字符串,必须要重新分配内存(先释放再申请),因为如果没有重新分配,字符串长度增大时会造成内存缓冲区溢出,字符串长度减小时会造成内存泄露...里面的元素,并且 SDS 不是以空字符串来判断是否结束,而是以 len 属性表示的长度来判断字符串是否结束。...⑤、兼容部分 C 字符串函数   虽然 SDS 是二进制安全的,但是一样遵从每个字符串都是以空字符串结尾的惯例,这样可以重用 C 语言库 中的一部分函数。 ⑥、总结 ?

    79300

    校长讲堂第九讲

    实际上,它并不总是这么做。譬如在一些编译器中,它的输出为 0 0 0 0 0 1 2 3 4。 为什么?因为 c 的声名是 char 而不是 int。...让我们再试试,为 r 分配一些内存: char r[100]; strcpy(r, s); strcat(r, t); 这只有在 s 和 t 所指向的字符串不很大的时候才能够工作。...不幸的是,C 要求我们为数组指定的大小是一个常数,因此无法确定 r 是否足够大。然而,很多 C 实现带有一个叫做 malloc()的库函数,它接受一个数字并分配这么多的内存。...因为 strcmp()总是通过其参数来查看内存地址的。...第二个问题的答案同样简单:如果待移位的数长度为 n,则移位的数量必须大于等于 0 并且严格地小于 n。因此,在一次单独的操作中不可能将所有的位从变量中移出。

    56431

    redis的底层数据结构

    ②、杜绝缓冲区溢出 我们知道在 C 语言中使用 strcat 函数来进行两个字符串的拼接,一旦没有分配足够长度的内存空间,就会造成缓冲区溢出。...而对于 SDS 数据类型,在进行字符修改的时候,会首先根据记录的 len 属性检查内存空间是否满足需求,如果不满足,会进行相应的空间扩展,然后在进行修改操作,所以不会出现缓冲区溢出。...③、减少修改字符串的内存重新分配次数 C语言由于不记录字符串的长度,所以如果要修改字符串,必须要重新分配内存(先释放再申请),因为如果没有重新分配,字符串长度增大时会造成内存缓冲区溢出,字符串长度减小时会造成内存泄露...里面的元素,并且 SDS 不是以空字符串来判断是否结束,而是以 len 属性表示的长度来判断字符串是否结束。...⑤、兼容部分 C 字符串函数 虽然 SDS 是二进制安全的,但是一样遵从每个字符串都是以空字符串结尾的惯例,这样可以重用 C 语言库 中的一部分函数。

    48130

    Stack and Heap 堆和栈的区别include

    堆(heap)的分配是在程序运行时完成的,分配速度较为缓慢,但是堆的可用空间非常的大。堆中的元素相互之间没有关联,各自都可以被任何时候随机访问。...- 程序结束后有系统释放 4、文字常量区 —常量字符串就是放在这里的。 程序结束后由系统释放 5、程序代码区—存放函数体的二进制代码。...堆:首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时, 会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序,另外,...但是速度, 也最灵活 2.5堆和栈中的存储内容 栈: 在函数调用时,第一个进栈的是主函数中后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈的...是在编译时就确定的; 但是,在以后的存取中,在栈上的数组比指针所指向的字符串(例如堆)快。

    1.2K80
    领券