做 malloc 和 new 返回一个 int 对齐的地址



在我之前提出的与按位运算有关的问题中,有人告诉我,如果char数组未与int地址对齐,则使用int指针访问char数组(一次对较大的字节块进行操作)的代码可能会出现问题。

然后,在C中思考,我想知道当malloc为未知类型分配内存时会发生什么。例如,如果我执行void *p = malloc(sizeof(int));,我是否获得有效的字符/整数/长对齐内存地址?

根据 SO 中引用该标准的一些答案,"返回的指针应适当对齐,以便可以转换为任何完整对象类型的指针"。

因此,我知道在这种情况下我可以毫无问题地从char*int*

char *p = malloc(16);
int *n = (int*)p; // use n a base of an array of 16 / sizeof(int) ints

正确吗?

转到C++,标准中似乎出现了相同的规则。那么,如果我这样做,我是否可以假设没有对齐风险?

char *p = new char[16];
int *n = reinterpret_cast<int*>(p);
是的

,C 和 C++ 中的malloc以及 C++ 中的 new char[N] 都返回最大对齐的指针。对齐方式是 或 max_align_t 的类型。

GCC-4.8

在这方面有一个错误,在 GCC-4.9 中修复。只需包含并使用不带std::前缀的::maxalign_t

过度对齐类型(即对齐方式大于上述最大值的类型)的支持是实现定义的。 例如,Posix 提供了posix_memalign来分配具有更大对齐方式(例如页面对齐)的内存。

char* p = new char[16];
int* n = reinterpret_cast<int*>(p);

这很好,但更好的是:

char* p = new char[16];
int* n = static_cast<int*>(static_cast<void*>(p));

或者,您可以使用 C++ 的operator new,如下所示:

void* p = operator new(16);
int* n = static_cast<int*>(p);

少了一个static_cast

malloc返回一个地址,该地址对于 C 中的任何基类型都正确对齐。这意味着它可以安全地转换为所有这些类型(int、长、double等)的指针。

最新更新