美文网首页iOS 编译原理
静态内存区域解析

静态内存区域解析

作者: 谦谦君子修罗刀 | 来源:发表于2017-06-03 00:08 被阅读61次

通常在代码中产生的bug,往往是源于概念不清晰。知己知彼百战不殆,对内存这块了如指掌,能极大优化代码的性能。

一、内存四区建立流程讲解

420E1EED-0A4C-402A-AB84-3ACEFC86E8E3.png

如上图所示,首先操作系统要把物理硬盘代码加载到内存中,加载完成后,操作系统会将代码分成四个区域,即堆区、栈区、全局区和常量区。最后,操作系统会找到main函数入口执行程序。这就是内存四区执行流程的说明。

二、内存四区存储说明
栈区:由编译器自动分配释放,存放函数的参数值、局部变量等。
堆区:由程序员动态申请与释放内存,通常用于存放new/malloc关键字创建的值。如果程序员不释放,程序结束时会由操作系统回收。
全局区:也叫静态区,用于存放常量和全局变量,由操作系统管理。全局变量和静态变量存储在一起,初始化的全局变量和静态变量在同一块区域,未初始化的存储在相邻的另一区域内。
程序代码区:存放函数体的二进制代码,由操作系统管理。

三、代码示例

char * getP1(){
    char *p1 = "abcdef";
    return p1;
}
char * getP2(){
    char *p2 = "abcdef2";
    return p2;
}
int main(int argc, const char * argv[]) {
    char *p1 = getP1();
    char *p2 = getP2();
    printf("打印地址:%s,%s\n,",p1,p2);
    printf("打印内容:%d,%d\n",p1,p2);
    
    return 0;
}

打印的结果:

5F6267E1-F728-42C2-93A7-7A1956BA404A.png
char * getP1(){
    char *p1 = "abcdef";
    return p1;
}
char * getP2(){
    char *p2 = "abcdef";
    return p2;
}
int main(int argc, const char * argv[]) {
    char *p1 = getP1();
    char *p2 = getP2();
    printf("打印地址:%s,%s\n,",p1,p2);
    printf("打印内容:%d,%d\n",p1,p2);
    
    return 0;
}

打印结果:

B04FA0BE-D6BF-405C-BEB8-75C32160A58E.png

让人疑惑的是,为何在不同函数中声明的不变量,打印的会是同样的内容和地址。

C3944F50-ACA9-4347-BEFD-2D92A7A30D43.png

在示例中的代码中,操作系统进入到main函数的入口,将变量p1,p2放入到栈中。p1和p2分别用来接收getP1()和getP2()函数返回的首地址,在64位机中,只占用内存的8个字节,在getP1()函数中,也有一个p1变量,因此把它放入到内存的栈中,把常量“abcdef”放入到全局区中。此时,函数getP1()中的p1指针是指向“abcdef”,假设该常量的值是“0xa11”,那就将这个地址赋给函数中的p1,函数的p1要将首地址放回给main函数中的p1变量。那么main函数中的p1也会指向上文中的首地址。这就是p1指针的内存解析说明。

在编译程序时,若编译器检测到全局区有两个同样的值,它就会代码进行优化,在内存中只保留一份。当这两个相同的值放置到全局区时,他会统一将这两个值合成一个,以避免造成内存空间的浪费。

所以,当编译器发现两个函数中变量的值相同之后,就将它们合二为一,p2指针按照上文中p1的分配方式对内存进行分配。到最后,就会发现p2指针与p1指针指向了相同的地址,且它们的内容也是相同的。这就是静态内存区域的全部解析。

相关文章

  • 静态内存区域解析

    通常在代码中产生的bug,往往是源于概念不清晰。知己知彼百战不殆,对内存这块了如指掌,能极大优化代码的性能。 一、...

  • iOS知识点

    1、内存的几大区域 iOS的内存分布区域大致分为:栈区(stack)、堆区(heap)和全局静态区(static)...

  • JVM内存区域解析

    “原创精选,转载注明出处,三克油”@Date 2017.05.24 概念介绍(基于JDK7) 堆(分代收集算法)年...

  • Java内存区域解析

    java虚拟机在执行java程序的过程中会把它所管理的内存区域划分为若干个不同的数据区域.每个区域都有各自的用途,...

  • 内存介绍

    虚拟内存总体分五大区域,栈区(堆栈),堆区(托管堆),常量,静态(静态未初始化区,和静态初始化区)其他区域**栈区...

  • Javascript方法小札记

    1静态方法 存储在运行内存上的静态区域,该类方法由JS体系内类所持有。 varBaseClass=newFunct...

  • JavaScript基础知识

    内存管理机制 内存可以分为三大区域: 代码区:存放程序编译后的机器指令 静态数据区:存放全变变量,静态变量,字符串...

  • malloc、calloc、realloc的区别?

    (1)C语言跟内存分配方式<1>从静态存储区域分配. 内存在程序编译的时候就已经分配好,这块内存在程序...

  • 高质量C++编程指南 ----内存管理

    7. 内存管理 7.1 内存分配方式 内存分配方式有三种: (1) 从静态存储区域分配。内存在程序编译的时候就已经...

  • 3. 内存管理——基础知识

    内存管理和内存分配是操作系统需要重点考虑的问题。以下简单的的写下内存相关的知识。 内存主要分为五个区域:静态区(....

网友评论

    本文标题:静态内存区域解析

    本文链接:https://www.haomeiwen.com/subject/bkhpfxtx.html