既然malloc的结果似乎不能保证与任何东西对齐,那么它是否可用呢?

tjrkku2a  于 2023-01-12  发布在  其他
关注(0)|答案(1)|浏览(108)

我最近了解到,对某个对象(uint32_t* foo = (uint32_t*)7; *foo = 5;)解引用一个未对齐的指针实际上是未定义的行为:
C11第6.2.8节:对象对齐:
完整的对象类型具有对齐要求,这些要求对可以分配该类型对象的地址施加限制。对齐是一个实现定义的整数值,表示可以分配给定对象的连续地址之间的字节数。对象类型对该类型的每个对象施加对齐要求:可以使用_Alignas关键字来请求更严格的对齐。
好的,非常有趣。但是malloc似乎根本不关心对齐:

7.22.3.4malloc函数

概要

#include <stdlib.h>
void *malloc(size_t size);

说明

malloc函数为大小由size指定且值不确定的对象分配空间。

退货

malloc函数返回一个空指针或一个指向已分配空间的指针。
因此:像下面这样的行为调用未定义行为的可能性不是很真实的吗?

uint32_t* a = malloc(10*sizeof(uint32_t));
*a = 7;

毕竟,我们不能保证malloc的返回值与任何值对齐。

fwzugrvs

fwzugrvs1#

在引用malloc函数的部分之前,你似乎跳过了标准中的一个段落,从this C17 Draft Standard开始--在C11和其他更高版本的标准中也是如此(粗体强调是我的):

7.22.3内存管理功能

1 由对aligned_alloccallocmalloc、未指定和realloc函数。分配成功时返回的指针***已适当对齐,以便可以将其分配给指向具有基本对齐要求的任何类型对象的指针***然后用于访问所分配的空间中的这样的对象或这样的对象的阵列(直到空间被显式释放)。已分配对象的生存期从分配到释放。每次这样的分配都将产生一个指针,指向一个与其他对象不相交的对象。返回的指针指向已分配空间的开始(最低字节地址)。如果无法分配空间,则返回空指针。如果请求的空间大小为零,则行为由实现定义:返回空指针以指示错误,或者行为就好像大小是某个非零值,除了返回的指针不应用于访问对象。
所以,你的问题的基本前提是错误的,(成功)调用malloc所返回的指针将可用于 * 几乎任何 * 类型的对象,就对齐要求而言。对于有 * 扩展对齐 * 要求的对象,情况 * 可能 * 有所不同,在这种情况下,应该使用更具体的分配技术。

相关问题