您的位置:首页 > 教育 > 培训 > 南昌建筑工程公司_电子商务怎么样_百度推广售后_郑州网站运营

南昌建筑工程公司_电子商务怎么样_百度推广售后_郑州网站运营

2025/3/17 10:05:16 来源:https://blog.csdn.net/weixin_49962210/article/details/146187252  浏览:    关键词:南昌建筑工程公司_电子商务怎么样_百度推广售后_郑州网站运营
南昌建筑工程公司_电子商务怎么样_百度推广售后_郑州网站运营

一、内存分布图

直接上图分析 

向下增长的栈:栈顶指针(SP)从高地址向低地址移动;

向上增长的栈:栈顶指针(SP)从底地址向高地址移动。 

验证代码(linux平台下测试,这个栈的生长方向不同平台会有些差异,感兴趣的话可自行测试~):

#include <stdlib.h>
#include <stdio.h>
#include <sys/mman.h>
#include <unistd.h>int unInitialG;
static int sUnInitialG;
int initialG = 0;
static int sInitialG = 10;
const int cG = 0;void testStackIncreaseDirection(){int a;int b;printf("stack testStackIncreaseDirection allocation (stack):     %p\n", &a);printf("stack testStackIncreaseDirection allocation (stack):     %p\n", &b);
}int main() {int a = 0;int b = 0;int c = 0;void* heap_ptr = malloc(1024);  // 通过 malloc 分配(通常在堆)void* mmap_ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);  // mmap 分配(通常在映射区域)printf("stack hight allocation (stack):     %p\n", &a);printf("stack middle allocation (stack):    %p\n", &b);printf("stack slow allocation (stack):      %p\n", &c);testStackIncreaseDirection();printf("Mmap hight allocation (mmap):       %p\n", mmap_ptr);printf("Heap slow allocation (malloc):      %p\n", heap_ptr);printf("bss1 allocation (.bss):             %p\n", &sUnInitialG);printf("bss2 allocation (.bss):             %p\n", &unInitialG);printf("data1 allocation (.data):           %p\n", &initialG);printf("data2 allocation (.data):           %p\n", &sInitialG);printf("data3 allocation (.data):           %p\n", &cG);free(heap_ptr);       // 释放 malloc 分配的内存munmap(mmap_ptr, 4096);  // 释放 mmap 分配的内存return 0;
}

结果图如下:

 

 注意:在一个函数里面的局部变量,比如void testStackIncreaseDirection()函数,先定义的后压栈。 

二、C++的内存怎么分配?

简洁版 

  1. 全局变量,全局静态变量未初始化的存放在(.bss);
  2. 全局变量,全局静态变量初始化的存放在(.data);
  3. 函数参数、局部变量和函数返回值存放在栈区(stack);
  4. malloc和new申请的内存存放在堆区(heap),详细区别如下所示;
  5. 可执行文件存放在代码区(text)。

详细版 

(1)代码区(Code Segment / Text Segment)

  • 存放程序的 可执行代码(即编译后的指令)。
  • 只读(防止程序意外修改自身代码)。
  • 共享(多个进程可共享相同的代码段)。

(2)全局/静态区(Global & Static Segment)

  • 存放 全局变量静态变量(static 变量)
  • 变量的生命周期贯穿整个程序运行期(直到进程结束)。
  • 初始化的变量存放在 .data 段,未初始化的存放在 .bss 段。

(3)栈区(Stack Segment)

  • 由编译器自动分配释放,用于存储局部变量、函数参数、返回地址等
  • 栈是 后进先出(LIFO) 结构,每进入一个函数,就会在栈上分配一块新的内存,函数执行完毕后自动释放。

特点

  • 速度快(直接由 CPU 指令管理)。
  • 不需要手动管理内存。
  • 受限于栈空间大小(通常 1~8MB),递归太深可能导致栈溢出(Stack Overflow)

(4)堆区(Heap Segment)

  • 由程序员手动管理(使用 new / deletemalloc / free)。
  • 适合大对象动态分配的对象(大小和生存期不确定)。
  • 堆区通常比栈大,但分配/释放效率比栈低。

特点

  • 适用于大对象、动态数组、类对象
  • 程序员必须手动管理,否则可能会导致内存泄漏

(5)常量区(Readonly Data Segment)

  • 存储 字符串字面量const 修饰的全局变量
  • 该区域的内容通常不可修改(否则可能会导致段错误 Segmentation Fault)。

三、栈和堆的对比

对比项栈(Stack)堆(Heap)
分配方式由编译器自动分配由程序员手动分配 (new / malloc)
释放方式由编译器自动释放需要手动释放 (delete / free)
访问速度快(LIFO 结构,CPU 指令直接管理)慢(自由分配,可能导致碎片化)
生命周期随函数调用自动管理需要程序员手动管理
大小较小(一般 1MB~8MB)较大(可动态扩展)
典型应用局部变量、函数参数、返回地址动态数组、对象、大型数据结构

四、malloc vs new 的核心区别

区别点mallocnew
函数 / 关键字C 标准库函数C++ 关键字
返回类型void*(需要强制转换)具体类型指针(自动转换)
初始化不会初始化(内存内容不确定)调用构造函数,自动初始化
内存分配方式使用 heap manager 调用 sbrk() / mmap()使用 operator new(可能使用 malloc 底层分配)
释放方式free(ptr)delete ptr(调用析构函数)
适用于C 语言和 C++ 低级内存操作C++ 面向对象编程(支持构造 / 析构函数)

五、malloc 分配流程

调用 malloc(size) 时的底层步骤:

  1. 检查 size
    • size < 128KB,使用 sbrk() 增长堆。
    • size ≥ 128KB,使用 mmap() 直接映射内存(调用 mmap() 直接映射内存页)。
  2. 检查 free list(空闲链表)
    • free list 中有足够大的块,则复用空闲块。
    • 若没有足够的空闲块,则调用 sbrk()mmap()
  3. 返回指针,供程序使用。

六、malloc/free vs new/delete 的使用场景

使用场景推荐方式
C 语言malloc/free
C++ 对象(类)new/delete
需要构造函数 / 析构函数new/delete
简单数据结构(如 int[]new/deletestd::vector
手动内存管理,性能优化(如内存池)malloc/free

end!

有哪里不对的欢迎指出,批评指正,谢谢。

制作不易,麻烦观众老爷点个赞,再走呗,鼓励一下,感谢! 

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com