美文网首页系统
C语言内存模型

C语言内存模型

作者: 第八区 | 来源:发表于2017-07-04 15:56 被阅读52次

内存四区

1栈区

由编译器自动分配释放 ,存放函数的参数值,局部变量的值等

2.堆区

一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回

3.静态全局数据区

主要包括静态全局区和常量区

  • char *s = "HelloWorld";//该字符串 HelloWorld 即存放于文字常量区,不可修改。但指针s存放于栈区。
    若在程序中尝试对其修改(例如尝试修改第一个字符 *s = 'h';),将出现编译可通过,运行报错的情况。
  • 同时因注意它与const修饰的变量之间的区别:
    char aa = 'A';//aa存放于栈区
    const char bb = 'B'; //bb同样存放于栈区
    const修饰的变量仅仅用于告诉编译器bb是一个常量,如果后续的程序中有出现尝试修改bb的操作时,编译将报错。
    这种写法主要是为了防止程序员在后续的代码中误操作bb变量而添加的一个约束条件,并不会影响它存放的位置。
4.代码区

存放函数体的二进制代码。用于存储程序编译连接后生成的二进制机器码指令的内存区域

区别
  • 能否产生碎片
    对于堆来讲,频繁的new/delete势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。对于栈来讲,则不会存在这个问题。
  • 生长方向不同
    对于堆来讲,生长方向是向上的,也就是向着内存地址增加的方向;对于栈来讲,它的生长方式是向下的,是向着内存地址减小的方向增长。
  • 分配方式不同
    堆都是动态分配的;栈有静态和动态两种分配方式。静态分配由编译器完成,比如局部变量的分配。动态分配由alloca函数进行、但栈的动态分配和堆是不同的,它的动态分配由编译器进行释放,无需我们手工实现。
  • 分配效率不同
    栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。堆则是c/c++库函数提供的,机制很复杂。库函数会按照一定的算法进行分配。显然,堆的效率比栈要低得多。
  • Buf的生长方向
    如数组生长方向都是由低地址到高地址生长,和栈的生长方向无关

实验

代码
int add(int x, int y);
int sub(int x, int y);

int main() {
    int c = 30;
    int d[10];
    int *p=malloc(sizeof(int)*2);
    int *p1=malloc(sizeof(int));
    printf("-----static--------\n");
    printf("%x\n", &a);
    printf("%x\n", &b);
    printf("------stack-------\n");
    printf("%x\n", &c);
    printf("%x\n", &d);
    printf("%x\n", &p);
    printf("%x\n", &p1);
    add(a,b);
    sub(b,c);
    printf("------heap-------\n");
    printf("%x\n", p);
    printf("%x\n", p1);
    printf("------code-------\n");
    printf("%x\n", add);
    printf("%x\n", sub);
}

int add(int x, int y) {
    printf("%x\n", &x);
    printf("%x\n", &y);
    return x + y;
}

int sub(int x, int y) {
    printf("%x\n", &x);
    printf("%x\n", &y);
    return x - y;
}
结果
-----static--------
405008
40500c
------stack-------
28ff3c
28ff14
28ff10
28ff0c
28fef0
28fef4
28fef0
28fef4
------heap-------
4629f0
462a00
------code-------
401933
401969
  • 栈地址的增长方向是由高->低
  • 堆地址的增长方向是由低->高
  • 静态全局数据区的增长方向是由低->高

相关文章

  • iOS面试:iOS内存分区

    OC语言是C语言的超集,所以先了解C语言的内存模型的内存管理会有很大的帮助。C语言的内存模型分为5个区:栈区、堆区...

  • Objective-C-(二)内存管理

    由于Objective-C是基于C语言的,在了解Objective-C内存管理前应该先了解下C语言的内存模型。 简...

  • iOS修饰符详解与block使用精粹

    #C语言内存分配 Objective-C从名字来看就可以知道是一门超C语言,所以了解C语言的内存模型对于理解Obj...

  • C语言内存模型

    内存四区 1栈区 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等 2.堆区 一般由程序员分配释放, 若程...

  • 什么是堆栈,以及堆栈的区别

    首先,讨论的堆和栈指的是内存中的“堆区”和“栈区”,OC语言是C语言的超集,所以先了解C语言的内存模型的内存管理会...

  • iOS 堆和栈的区别

    首先,讨论的堆和栈指的是内存中的“堆区”和“栈区”,OC语言是C语言的超集,所以先了解C语言的内存模型的内存管理会...

  • C语言内存四驱模型

    一、数据类型的本质 1、数据类型可以理解为创建变量的模具,是固定内存大小的别名。 2、数据类型的作用:编译...

  • C/C++/OC 内存布局

    这几天看了些关于内存布局的文章,发帖总结摘录下重点。 C语言的内存模型 程序代码区(code area) 存放函数...

  • Golang面向并发的内存模型

    面向并发的内存模型 在早期,CPU都是以单核的形式顺序执行机器指令。Go语言的祖先C语言正是这种顺序编程语言的代表...

  • 第一章:Redis初识

    Redis特性 速度快 数据存储在(内存)中 (主要原因) C语言编写(50000行) 单线程模型...

网友评论

    本文标题:C语言内存模型

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