由于 malloc 的结果似乎不能保证与任何内容对齐,它是否可用?

Che*_*ron 0 c malloc alignment language-lawyer

我最近了解到,取消引用未与某个对象 ( ) 对齐的指针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;
Run Code Online (Sandbox Code Playgroud)

毕竟,我们无法保证 的返回值与malloc任何内容对齐。

Adr*_*ica 8

您似乎跳过了标准中的一段,比您引用的有关该功能的部分稍早一点malloc。从这个 C17 标准草案\xe2\x80\x93 来看,它在 C11 和其他更高版本的标准中非常相似(粗体强调是我的):

\n
\n

7.22.3 内存管理函数

\n

aligned_alloc1 \xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0 通过连续调用、calloc、\nmalloc和函数分配的存储的顺序和连续性realloc未指定。如果分配成功,则\n返回的指针将被适当对齐,以便可以将其分配\n到具有基本对齐要求的任何类型对象的指针\n,然后用于访问空间中的此类对象或此类对象的数组。已分配(直到显式分配空间)。已分配对象的生命周期从分配开始一直延伸到释放为止。每个这样的分配都应产生一个指向与任何其他对象不相交的对象的指针。返回的指针指向已分配空间的起始位置(最低字节地址)。如果无法分配空间,则返回空指针。\n如果请求的空间大小为零,则行为\n由实现定义:要么返回空指针以指示\n错误,要么行为就像大小是某个非零值,\n除非返回的指针不应用于访问\n对象。

\n
\n

因此,您问题的基本前提是错误的,就其对齐要求而言,(成功)调用返回的指针malloc将可用于几乎任何类型的对象。对于具有扩展对齐的对象,情况可能有所不同有所不同,在这种情况下,应使用更具体的分配技术。

\n