Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/154.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 对齐的malloc c++;实施_C++_Memory_Malloc_Heap - Fatal编程技术网

C++ 对齐的malloc c++;实施

C++ 对齐的malloc c++;实施,c++,memory,malloc,heap,C++,Memory,Malloc,Heap,我发现了这段代码: void* aligned_malloc(size_t required_bytes, size_t alignment) { int offset = alignment - 1; void* P = (void * ) malloc(required_bytes + offset); void* q = (void * ) (((size_t)(p) + offset) & ~(alignment - 1)); return q; } 这是C++中对齐的Malo

我发现了这段代码:

void* aligned_malloc(size_t required_bytes, size_t alignment) {
int offset = alignment - 1;
void* P = (void * ) malloc(required_bytes + offset);
void* q = (void * ) (((size_t)(p) + offset) & ~(alignment - 1));
return q;
}

这是C++中对齐的Maloc的实现。对齐malloc是一个支持分配内存的函数,以便 返回的内存地址可以被二的特定幂整除。 例如:

align_malloc(1000128)将返回一个128的倍数的内存地址,该地址指向大小为1000字节的内存

但我不懂第四行。为什么总和是补偿的两倍

谢谢

为什么总和是补偿的两倍

偏移量
并不是两次求和。
偏移量的第一次使用是用于分配的大小:

void* p = (void * ) malloc(required_bytes + offset);
第二次是针对路线:

void* q = (void * ) (((size_t)(p) + offset) & ~(alignment - 1));
说明:
~(alignment-1)
是对
offset
的否定(请记住,
int offset=alignment-1;
),它为您提供了满足所请求的对齐所需的掩码。算术方面,添加偏移量并按位执行and(
&
)及其求反运算,可以得到对齐指针的地址

这个算法是如何工作的?首先,请记住对
malloc()
的内部调用是针对
required\u字节+offset
字节的。如中所示,不是您要求的对齐方式。例如,您希望以16的对齐方式分配10个字节(因此,所需的行为是分配从可被16整除的地址开始的10个字节)。因此,上面的
malloc()
将为您提供
10+16-1
=25个字节。不一定从正确的地址开始,因为它可以被16整除。但是这个
16-1
0x000F
,它的否定(
~
)是
0xFFF0
。现在我们按位应用如下:
p+15&0xFFF0
,这将导致每个指针
p
都是16的倍数

但是请稍候,为什么要首先添加对齐-1的偏移量呢?您这样做是因为一旦您得到由
malloc()返回的指针
p
为了找到最近的地址(即所请求对齐的倍数),您不能做的一件事是在
p
之前查找它,因为这可能会进入
p
之前分配的某个地址空间。为此,您首先要添加对齐-1,仔细想想,这正是您必须向前推进的最大值

*感谢用户DevSolar提供了一些额外的措辞

注1:对于这种工作方式,对齐必须是2的幂。此代码段不强制执行此操作,因此可能导致意外行为

注2:一个有趣的问题是,如何使用此函数的返回值为此类分配实现
free()
版本

为什么总和是补偿的两倍

偏移量
并不是两次求和。
偏移量的第一次使用是用于分配的大小:

void* p = (void * ) malloc(required_bytes + offset);
第二次是针对路线:

void* q = (void * ) (((size_t)(p) + offset) & ~(alignment - 1));
说明:
~(alignment-1)
是对
offset
的否定(请记住,
int offset=alignment-1;
),它为您提供了满足所请求的对齐所需的掩码。算术方面,添加偏移量并按位执行and(
&
)及其求反运算,可以得到对齐指针的地址

这个算法是如何工作的?首先,请记住对
malloc()
的内部调用是针对
required\u字节+offset
字节的。如中所示,不是您要求的对齐方式。例如,您希望以16的对齐方式分配10个字节(因此,所需的行为是分配从可被16整除的地址开始的10个字节)。因此,上面的
malloc()
将为您提供
10+16-1
=25个字节。不一定从正确的地址开始,因为它可以被16整除。但是这个
16-1
0x000F
,它的否定(
~
)是
0xFFF0
。现在我们按位应用如下:
p+15&0xFFF0
,这将导致每个指针
p
都是16的倍数

但是请稍候,为什么要首先添加对齐-1的偏移量呢?您这样做是因为一旦您得到由
malloc()返回的指针
p
为了找到最近的地址(即所请求对齐的倍数),您不能做的一件事是在
p
之前查找它,因为这可能会进入
p
之前分配的某个地址空间。为此,您首先要添加对齐-1,仔细想想,这正是您必须向前推进的最大值

*感谢用户DevSolar提供了一些额外的措辞

注1:对于这种工作方式,对齐必须是2的幂。此代码段不强制执行此操作,因此可能导致意外行为


注2:一个有趣的问题是,如何使用此函数的返回值实现此类分配的
free()
版本。

请注意,无法释放此函数分配的内存,因为内存块的原始地址已被丢弃。这有什么意义
malloc
已经为任何标量类型提供了对齐的存储。我也会远离任何显式转换为
void*
的代码(特别是考虑到它已经是malloc的返回类型!),就像你远离那些不断咬指甲的人一样——这太不卫生了。最后,为什么你在C++中使用Maloc?@ Sergya——它允许用户指定一些类型的歌剧所需要的对齐方式。