前言:

       1 若变量var要以2的N次幂对齐,以16 byte对齐为例,我们知道16=
0x10,那么16byte对齐的数值必须符合bit0~3均为0的规律,例如32=0x20,48=0x30等;

那么给定一个随机数,如何来达到bit0~3均为0的效果呢,var
&~0x0f即可。同理,若需32byte对齐,先看32byte的十六进制对应是什么,32=0x20,bit0~bit4需要全为0。达到32byte对齐需要var
&~0x1f才行。依次类推应该可以得出一个更通用的结论,若变量var需要以align byte(为2的N次幂)对齐,可以对当前数值var & ~(align
-1)即能达到目的。

2 这里又有个问题,如何实现任意字节的对齐呢?假设数值366,我就是想让他变成199的整数倍,366 - 366%199 =
199就能达到目的。那么想让他变成199*2 =398呢,388+199 - 388%199 = 398就达到了目的。

        3 cpu能访问的地址,一般都会要求至少4 byte对齐,所以没有2当中提到的可能性。

情景:

   
 基于ANSI的malloc/free实现align_malloc/align_free函数,实现2的N次幂字节对齐,假设要求64byte对齐。实现该项的重点就是要保存base_addr,这样才能正确的free掉分配的区域,防止内存泄露。测试代码如下:

   有一种特殊情形,就是当base_ptr本身已经对齐的情况下,仍然将base_ptr往上加align_bytes,已达到兼容性。
#include <stdio.h> #include <stdlib.h> void *align_ptr_malloc(int size,int
align_bytes) { void *base_ptr = NULL; void *mem_ptr = NULL; base_ptr =
malloc(size + align_bytes);//alloc alignbytes, rather than align_bytes-1,
because we need to store offset mem_ptr = (void *)((int)((int *)base_ptr +
align_bytes -1) & ~(align_bytes-1)); if(mem_ptr == base_ptr)//base_ptr already
align_bytes align { mem_ptr = base_ptr + align_bytes;//force move it to one
more alignbytes } *((int *)mem_ptr-1) = mem_ptr - base_ptr; printf("offset is
%d base prt %x mem_ptr %x\n",*((int *)mem_ptr -1),base_ptr,mem_ptr); return
mem_ptr; } void *align_ptr_free(void *ptr) { void *base_addr = NULL; printf("%x
%x\n",ptr,*((int *)ptr - 1)); base_addr = (void *)(ptr- *((int *)ptr-1));
printf("ptr %x base_addr %x\n",ptr,base_addr); free(base_addr); } void main() {
void *ptr; ptr = align_ptr_malloc(1024,64); printf("ptr %x\n",ptr);
align_ptr_free(ptr); }

   

技术
©2019-2020 Toolsou All rights reserved,
Python 读取Excel某一列|转存json11-5 指定位置输出字符串(精华)2020年8月2日 TypeScript 泛型的使用关于Navicat for mysql 的2003错误elementui select 获取 value(精华)2020年6月26日 C#类库 日志帮助类LED 滚动文字mybatis系列之返回结果映射Spark SQL-编程415状态码到后台错误