iOS:栈、堆、字符串常量区、全局区
内存概述
C语言的数据在运行之前,编译器会提前预留一些内存(text 代码区,BSS、data等),这些数据不是说编译器就能生成,而是告诉程序在程序启动时先创建并分配内存,这部分数据就是全局区。
全局区分程序区域和数据区域,也就是 text 和 data区域,其中 text 存放二进制代码, data 区域还可以细分成常量区、全局区(全局已初始化区和全局未初始化)区。
常量区存放一些字符串常量。全局区存放全局变量和静态局部变量,其中已经初始化的放在全局已初始化区,未初始化的放在全局未初始化区,在程序开始运行时被初始化成0。
程序运行之后也会生成堆区,堆区可以很大,用处也很多。其中一个作用就是作为栈使用,栈遵循FIFO的内存。
栈区内存由编译器控制,可以理解成编译器自动帮忙生成分配销毁内存的代码,栈区主要是用来存储局部变量和形参。
堆区是程序员主动分配和释放的内存,一般体现在 malloc()
之类的内存分配函数上。
结构图如下:
一、全局数据区
全局数据区名称很乱,反正就记住除了堆、栈、代码区,还有一个区域,就是全局数据区,它分为常量区、已初始化区和未初始化区,其存放的数据有:
- 全局变量(值可以在运行时被动态修改)
- 静态变量(static修饰的变量,包括静态局部变量,静态全局变量)
- 字符串常量(字符串常量因为可能在程序中多次被使用,所以在程序运行之前就会提前分配内存)
可以用这张图来理解:
字符串常量区
首先,字符串常量的意义就是在常量区存储一些已经使用了的,且没有指向的字符串常量。
比如说代码:
char *p = "abcde";
这个时候赋值给 p 的是"abcde"
首个元素的地址。
而不使用指针时:
char s[] = "abcde";
此时是在内存中创建了"abcde"
并赋值给了 s[]
。
也就是说 s[]
的内存中记录的就是 "abcde"
,而p中内存记录的是地址,这也就导致了使用指针的情况下"abcde"
无处安放,所以就存储在常量区。
另外,排除编译器设置,按照C语言的原始设计思想,如果有如下情况:
char *p1 = "abc";
char *p2 = "abc";
这种情况下,应该在常量区分配两块不同的内存,而有的编译器做了优化,所以会导致p1和p2指向的内存地址是一样的。
另外,不再需要纠结字符串常量到底存储在哪,只需要记住C语言中变量的赋值原则:非指针变量,拷贝内存中的表现形式(实际的值),指针变量,拷贝内存地址。
关于常量区,来看一段代码:
char array[] = "aaa"; // "aaa"存放在栈区的array[]内存上char *point = "aaa"; // "aaa"存放在常量区char *arrayP = array; // 栈区的指针变量arrayP指向栈区的内存地址NSLog(@"%s",point); // aaaNSLog(@"%s",arrayP); // aaaNSLog(@"%p",point); // aaaNSLog(@"%p",arrayP); // aaaarrayP[1] = 'b';NSLog(@"%s",arrayP); // abapoint[1] = 'b';
结果:
2020-01-03 17:08:51.949067+0800 XKTTTest[89302:73170332] point的值:aaa
2020-01-03 17:08:51.949212+0800 XKTTTest[89302:73170332] arrayP的值:aaa
2020-01-03 17:08:51.949310+0800 XKTTTest[89302:73170332] 指针point存储的地址值:0x1095541ec
2020-01-03 17:08:51.949402+0800 XKTTTest[89302:73170332] 指针arrayP存储的地址值0x7ffee66aa1ac
2020-01-03 17:08:51.949488+0800 XKTTTest[89302:73170332] aba
其结果是在最后一行崩溃,提示EXC_BAD_ACCESS (code=2, address=0x10493025d)
。其原因就是 point 指向常量区,常量区内存中的值不可更改。
可以再看一个例子加深理解:
int main() {@autoreleasepool {char string2[] = "abc"; // abc存储在栈中char *p = "abc"; // "abc"存储在常量区
// *p = '1'; //崩溃,常量区的值不可改变(那为什么全局变量的值可以改变?)char *p2 = string2;*p2 = '1'; //可以改变,因为string2是局部变量而不是字符串常量
// string2 = '1'; // 编译报错(Array type 'char [4]' is not assignable),因为string2是一个地址,地址不能改变printf("%s",string2);
}
结果:
1bc
另外,打印出来的两个内存地址可以看出0x1095541ec
远远小于
0x7ffee66aa1ac
,这是因为内存地址从代码区到栈区是依次增大的。
各个区域内存的举例
例子1
iOS:栈、堆、字符串常量区、全局区相关推荐
- c/c++教程 - 2.1 程序的内存模型 内存四区 代码区 全局区 堆区 栈区 new操作符
第2章为C++核心编程. 本阶段主要针对C++面向对象编程做详细讲解. 目录 1.内存分区模型 1.1 程序运行前(代码区.全局区) 1.2 程序运行后:(栈区.堆区) 1.3 new操作符(堆区内存 ...
- 【错误记录】C 语言中通过指针操作字符串常量出错记录 ( 只有 栈内存 或 堆内存 中的数据才能通过指针修改 | 不要通过指针修改常量区的字符串 )
文章目录 一.报错记录 二.修改方案 一.报错记录 执行下面的代码 , 报错如下 : 执行的错误代码 : #include <stdio.h> #include <stdlib.h& ...
- java 字符串 常量_Java进阶——Java中的字符串常量池
字符串常量池 JVM为了减少字符串对象的重复创建,其内部维护了一个特殊的内存,这段内存被成为字符串常量池(方法区中).实际上还有整型常量池.浮点型常量池等等.字符串常量池存放的是对象的引用,而不是对象 ...
- 基于STM32分析栈、堆、全局区、常量区、代码区、RAM、ROM
目录 总体介绍 栈区(stack) 堆区(heap) 全局区(静态区) .bss段 .data段 常量区 代码区 RAM和ROM.Flash Memory的物理特性 RAM ROM Flash Mem ...
- 内存区划分、内存分配、常量存储区、堆、栈、自由存储区、全局区[C++][内存管理]...
这可以帮助你深入了解程序的运行机制,由于自己还是一个初学者,因此大部分内容都只是转载. http://blog.sina.com.cn/s/blog_7edcf63b0100yhk9.html 一. ...
- C/C++内存分配、内存区划分、常量存储区、堆、栈、自由存储区、全局区(静态区)、代码区
C/C++内存分配.内存区划分.常量存储区.堆.栈.自由存储区.全局区 C++中,内存分成几个区: 栈(stack) 堆(heap) 自由存储区 全局/静态存储区 常量存储区 代码区 对于C++的内存 ...
- C和指针之动态内存分配堆、栈、全局区(静态区)、常量区对比总结学习笔记
一.各个区的介绍 1.栈区(stack)- 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等.其操作方式类似于数据结构中的栈. 2.堆区(heap) - 一般由程序员分配释放, 若程序员不 ...
- 内存区划分、内存分配、常量存储区、堆、栈、自由存储区、全局区[C++][内存管理][转载]...
http://www.cnblogs.com/JCSU/articles/1051579.html 一. 在c中分为这几个存储区 1.栈 - 由编译器自动分配释放 2.堆 - 一般由程序员分配释放,若 ...
- 12.JDK1.8 JVM运行时数据区域概览、各区域介绍、程序计数器、Java虚拟机栈、本地方法栈、堆、堆空间内存分配(默认情况下)、字符串常量池、元数据区、jvm参数配置
12.JDK1.8 JVM运行时数据区域概览 12.1.JDK1.8 JVM运行时数据区域概览 12.2.各区域介绍 12.3.各区域介绍 12.3.1.程序计数器 12.3.2.Java虚拟机栈 1 ...
- 栈区,堆区,全局区,文字常量区,程序代码区详解(程序中不同类型数据所在区)
一.预备知识-程序的内存分配 一个由C/C++编译的程序占用的内存分为以下几个部分 1.栈区(stack)- 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等.其 ...
最新文章
- 《深入理解计算机系统》学习心得二:关于show-bytes的 学习
- dijkstra 算法_最短路径问题Dijkstra算法详解
- 一个handle使用更新线程的实例
- 第一个只出现一次的字符位置
- python_ 学习笔记(hello world)
- Xcode 不用签名编译程序
- api 定位 微信小程序 精度_一行代码区分微信小程序或QQ小程序
- scala学习笔记-Map与Tuple(10)
- html主要的骨架结构
- newtonsoft 数组反序列化_漏洞学习篇之反序列化
- 大数据分析平台如何选择
- asp.net门诊收费管理系统
- Java电商项目-5.内容管理cms系统
- 软件开发各类文档模板
- 整理一个将qq音乐的歌单导入到苹果音乐中的方法
- 集团公司预算控制与网上费用报销系统
- 桥接模式和适配器模式的区别
- JAVA中多态以及向上转型向下转型、重写的讲解
- FTP搜索引擎开发文档(任务概述与需求部分)
- CyberArticle(eLib电子图书馆)网文快捕