malloc(malloc在32位编译系统中分配的地址会8字节对齐,64为编译系统中会8或者16字节对齐)

2024-03-01 00:08

本文主要是介绍malloc(malloc在32位编译系统中分配的地址会8字节对齐,64为编译系统中会8或者16字节对齐),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

了解malloc分配策略的人都知道,malloc在32位编译系统中会8字节对齐,64为编译系统中会8或者16字节对齐。

故32位malloc分配后的首地址肯定是8的整数倍。

       举例说明:
32位系统环境, 假设按4字节对齐,分配8字节的存储空间存储long long型的内容。
malloc获取地址为0x1acf3014(4字节对齐), 返回给用户的地址为0x1acf300c(实际存储数据的地址),  如果long long
型的数据放入这个地址,由于__alignof__(long long)=8,要求8字节对齐。所以该数据由于内存未对齐访问效率低下,甚

至访问出错。

         如果在32位系统自己实现的malloc函数空间不按照8字节对齐,会产生问题(如果自己实现的malloc函数返回的是4字节对齐的内存地址,比如0x0000000c,而分配的此首地址0x0000000c不能被8整除,但是我要在0x0000000c-0x00000014 放置longlong 8个字节的变量类型就会出现问题),此问题会类似我的另一篇文章如果指定在不能被4整除的内存地址上放置int型变量会发生什么。

至于什么是内存对齐、为什么要做内存对齐,这涉及到计算机体系结构相关知识。已经有很多前辈写了许多
关于内存对齐的相关文章,如果感兴趣可以google。
malloc的相关源代码如下:

#ifndef INTERNAL_SIZE_T
#define INTERNAL_SIZE_T size_t
#endif

/* The corresponding word size */
#define SIZE_SZ                (sizeof(INTERNAL_SIZE_T))

#ifndef MALLOC_ALIGNMENT
/* #define MALLOC_ALIGNMENT       (2 * SIZE_SZ < __alignof__ (long double) \
                ? __alignof__ (long double) : 2 * SIZE_SZ)
*/
#define MALLOC_ALIGNMENT       (2 * SIZE_SZ)
#endif


MALLOC_ALIGNMENT 就是malloc的最小对齐参数,也是研究的重点。那这里为什么要2*SIZE_SZ对齐呢? 
其实上面红色字体才是MALLOC_ALIGNMENT宏的正确定义。 只是这样定义会带来一些兼容性的问题,故而采用
2*SIZE_SZ定义(对于大多数平台这种定义也是正确的), 看来这里只是想表示最大元类型的字节数的意思。我们
知道元类型、结构类型等都是要作内存对齐的(主要是从寻址和访问效率上考虑)。那么我们在采用动态内存分配的
时候也要保证存储的数据是内存对齐的。但malloc分配内存的时候不知道内存的用途。所以就只有按最大元类型对齐。
举例说明:
32位系统环境, 假设按4字节对齐,分配8字节的存储空间存储long long型的内容。
malloc获取地址为0x1acf3014(4字节对齐), 返回给用户的地址为0x1acf300c(实际存储数据的地址),  如果long long
型的数据放入这个地址,由于__alignof__(long long)=8,要求8字节对齐。所以该数据由于内存未对齐访问效率低下,甚
至访问出错。 
动态分配内存对齐一般是按系统最大元类型的对齐要求来对齐内存的。 这个值就是最小的对齐参数。小于这个值就会出
现内存无法对齐的现象。 当然选择比这个值大是没有问题的(比如16)。

以上是我个人的理解,如有错误,欢迎批评指正。

这篇关于malloc(malloc在32位编译系统中分配的地址会8字节对齐,64为编译系统中会8或者16字节对齐)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/760542

相关文章

Go语言使用Buffer实现高性能处理字节和字符

《Go语言使用Buffer实现高性能处理字节和字符》在Go中,bytes.Buffer是一个非常高效的类型,用于处理字节数据的读写操作,本文将详细介绍一下如何使用Buffer实现高性能处理字节和... 目录1. bytes.Buffer 的基本用法1.1. 创建和初始化 Buffer1.2. 使用 Writ

.NET利用C#字节流动态操作Excel文件

《.NET利用C#字节流动态操作Excel文件》在.NET开发中,通过字节流动态操作Excel文件提供了一种高效且灵活的方式处理数据,本文将演示如何在.NET平台使用C#通过字节流创建,读取,编辑及保... 目录用C#创建并保存Excel工作簿为字节流用C#通过字节流直接读取Excel文件数据用C#通过字节

字节面试 | 如何测试RocketMQ、RocketMQ?

字节面试:RocketMQ是怎么测试的呢? 答: 首先保证消息的消费正确、设计逆向用例,在验证消息内容为空等情况时的消费正确性; 推送大批量MQ,通过Admin控制台查看MQ消费的情况,是否出现消费假死、TPS是否正常等等问题。(上述都是临场发挥,但是RocketMQ真正的测试点,还真的需要探讨) 01 先了解RocketMQ 作为测试也是要简单了解RocketMQ。简单来说,就是一个分

常用的jdk下载地址

jdk下载地址 安装方式可以看之前的博客: mac安装jdk oracle 版本:https://www.oracle.com/java/technologies/downloads/ Eclipse Temurin版本:https://adoptium.net/zh-CN/temurin/releases/ 阿里版本: github:https://github.com/

webapp地址

F:\LSP\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps

【JavaScript】LeetCode:16-20

文章目录 16 无重复字符的最长字串17 找到字符串中所有字母异位词18 和为K的子数组19 滑动窗口最大值20 最小覆盖字串 16 无重复字符的最长字串 滑动窗口 + 哈希表这里用哈希集合Set()实现。左指针i,右指针j,从头遍历数组,若j指针指向的元素不在set中,则加入该元素,否则更新结果res,删除集合中i指针指向的元素,进入下一轮循环。 /*** @param

Jenkins 插件 地址证书报错问题解决思路

问题提示摘要: SunCertPathBuilderException: unable to find valid certification path to requested target...... 网上很多的解决方式是更新站点的地址,我这里修改了一个日本的地址(清华镜像也好),其实发现是解决不了上述的报错问题的,其实,最终拉去插件的时候,会提示证书的问题,几经周折找到了其中一遍博文

NGINX轻松管理10万长连接 --- 基于2GB内存的CentOS 6.5 x86-64

转自:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=190176&id=4234854 一 前言 当管理大量连接时,特别是只有少量活跃连接,NGINX有比较好的CPU和RAM利用率,如今是多终端保持在线的时代,更能让NGINX发挥这个优点。本文做一个简单测试,NGINX在一个普通PC虚拟机上维护100k的HTTP

LeetCode:64. 最大正方形 动态规划 时间复杂度O(nm)

64. 最大正方形 题目链接 题目描述 给定一个由 0 和 1 组成的二维矩阵,找出只包含 1 的最大正方形,并返回其面积。 示例1: 输入: 1 0 1 0 01 0 1 1 11 1 1 1 11 0 0 1 0输出: 4 示例2: 输入: 0 1 1 0 01 1 1 1 11 1 1 1 11 1 1 1 1输出: 9 解题思路 这道题的思路是使用动态规划

string字符会调用new分配堆内存吗

gcc的string默认大小是32个字节,字符串小于等于15直接保存在栈上,超过之后才会使用new分配。