C++ 什么';对齐C+的目的是什么+;指针位置

C++ 什么';对齐C+的目的是什么+;指针位置,c++,pointers,opencv,C++,Pointers,Opencv,我现在正在阅读OPENCV的源代码,这是一个计算机视觉开源库。我对这个函数感到困惑: #define CV_MALLOC_ALIGN 16 void* fastMalloc( size_t size ) { uchar* udata = (uchar*)malloc(size + sizeof(void*) + CV_MALLOC_ALIGN); if(!udata) return OutOfMemoryError(size); uchar** adata

我现在正在阅读OPENCV的源代码,这是一个计算机视觉开源库。我对这个函数感到困惑:

#define CV_MALLOC_ALIGN 16
void* fastMalloc( size_t size )
{
    uchar* udata = (uchar*)malloc(size + sizeof(void*) + CV_MALLOC_ALIGN);
    if(!udata)
        return OutOfMemoryError(size);
    uchar** adata = alignPtr((uchar**)udata + 1, CV_MALLOC_ALIGN);
    adata[-1] = udata;
    return adata;
}

/*!
  Aligns pointer by the certain number of bytes

  This small inline function aligns the pointer by the certian number of bytes by
  shifting it forward by 0 or a positive offset.
 */
template<typename _Tp> static inline _Tp* alignPtr(_Tp* ptr, int n=(int)sizeof(_Tp))
{
    return (_Tp*)(((size_t)ptr + n-1) & -n);
}
#定义CV_MALLOC_ALIGN 16
void*fastMalloc(大小)
{
uchar*udata=(uchar*)malloc(尺寸+尺寸(空心*)+CV\u malloc\u对齐);
如果(!udata)
返回OutOfMemoryError(大小);
uchar**adata=alignPtr((uchar**)udata+1,CV\u MALLOC\u ALIGN);
adata[-1]=udata;
返回adata;
}
/*!
按一定的字节数对齐指针
这个小的内联函数按字节数对齐指针
将其向前移动0或正偏移量。
*/
模板静态内联_-Tp*alignPtr(_-Tp*ptr,int n=(int)sizeof(_-Tp))
{
返回(_-Tp*)((大小)ptr+n-1)和-n);
}

fastMalloc
用于为指针分配内存,指针调用
malloc
函数,然后调用
alignPtr
。我不太明白为什么分配内存后调用
alignPtr
?我的基本理解是,通过这样做,机器找到指针的速度要快得多。在互联网上能找到关于这个问题的一些参考资料吗?对于现代计算机,仍然需要执行此操作吗?如有任何意见,将不胜感激

某些平台要求某些类型的数据出现在某些字节边界上(例如:-某些编译器 要求指针存储在4字节边界上)

这称为对齐,它需要在对象的数据内(可能在数据的末尾)添加额外的填充

编译器可能会在找不到正确对齐的情况下崩溃,或者在读取该数据时可能存在性能瓶颈(因为需要读取两个块才能获得相同的数据)

根据评论编辑:-

程序的内存请求通常由内存分配器处理。一个这样的内存分配器是固定大小的分配器。固定大小分配返回指定大小的块,即使请求的内存小于该特定大小。因此,在这样的背景下,让我试着解释一下这里发生了什么:-

uchar* udata = (uchar*)malloc(size + sizeof(void*) + CV_MALLOC_ALIGN);
这将分配的内存量等于
请求的内存+随机大小
。这里的
random\u size
填补了空白,使其适合为固定分配方案指定的大小

uchar** adata = alignPtr((uchar**)udata + 1, CV_MALLOC_ALIGN);

这正试图将指针与上述特定边界对齐。

它分配的块比要求的块大一点

然后将
adata
设置为下一个正确分配字节的地址(添加一个字节,然后向上取整到下一个正确对齐的地址)

然后,它将原始指针存储在新地址之前。我假设这是后来用来释放最初分配的块

然后我们返回新地址


这只有在
CV\u MALLOC\u ALIGN
MALLOC
保证的对齐更严格的情况下才有意义-可能是缓存线?

不仅是编译器,还有CPU。但是对象是通过
MALLOC
分配的,它已经为任何类型的对象(C99,7.20.3p1)返回一个适当对齐的指针[…]@ouah:这可能是为了缓存对齐而在更大的边界上对齐某个对象。“对于任何类型的对象”不包括使用
movaps
指令加载的浮点数,这些指令要求例如16字节对齐。可能是为了缓存或特殊指令。