[读书笔记]程序员的自我修养(10)

本文深入探讨了内存管理的关键概念,包括段错误产生的原因、堆栈的工作原理及其在程序中的作用,以及不同编程语言中内存分配的特性。文章还介绍了调用惯例、C++中的返回值优化、堆内存管理及分配算法等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第十章 内存

1. 段错误,segment fault,最普遍的原因:
程序员将指针初始化为NULL,之后却没有给它一个合理的值就开始使用指针。
程序员没有初始化栈上的指针,指针值一般会是随机数,之后就直接开始使用指针。

2. 堆栈,保存活动记录(堆栈帧)
栈底:0xbfffffff, esp寄存器指向栈顶,保存的内容:
函数的返回地址和参数
临时变量:包括函数的非静态局部变量以及编译器自动生成的其他临时变量
保存的上下文:包括的函数调用前后需要保持不变的寄存器

ebp:帧指针,指向函数活动记录的一个固定位置。(返回地址下信息地址)

函数记录结构:
把所有或一部分参数压入栈中,如果有其他参数没有入栈,那么使用某些特定的寄存器传递
把当前指令的下一跳指令的地址压入栈中
跳转导函数体执行

3. 调用惯例
在C语言里默认为cdecl(非标准关键字),在gcc中是__attribute__((cdecl)),参数从右至左顺序压栈,函数调用方完成出栈,名字修饰直接在函数名称前加1个下划线

4. c++返回值优化,因为在c++里返回一个对象的时候,对象要经过2次拷贝构造函数的调用才能够完成返回对象的传送。

5. 堆
系统调用的开销较大
Linux进程堆:brk()和mmap()[系统页大小的整数倍,同windows下的VirtualAlloc]系统调用
windows进程堆:堆管理器     HeapCreate,HeapAlloc,HeapFree,HeapDestroy,默认堆的大小为1M

使用malloc调用会不会用到系统调用或者API,应该看当前进程向操作系统批发的空间够不够用。

堆不是总是向上增长的

不能重复两次释放堆里的同一片内存

malloc申请的内存在进程结束后不会存在

malloc申请的虚拟空间是连续的,申请的物理空间是不一定连续的

堆分配算法:空闲链表,位图,对象池

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值