英文:
Since the result of malloc does not seem to be guaranteed to be aligned to anything, is it even usable?
问题
最近我了解到,对于某个对象而言,对其进行解引用(uint32_t* foo = (uint32_t*)7; *foo = 5;
)如果未对齐,实际上是未定义行为:
C11章节6.2.8:对象的对齐要求:
完整对象类型具有对齐要求,这些要求限制了可以为该类型的对象分配的地址。对齐是一个实现定义的整数值,表示给定对象可以分配在连续地址之间的字节数。对象类型对该类型的每个对象都施加了对齐要求:可以使用
_Alignas
关键字请求更严格的对齐。
好的,非常有趣。但是 malloc
似乎完全不关心对齐:
7.22.3.4 malloc
函数
概要
#include <stdlib.h>
void *malloc(size_t size);
描述
malloc
函数分配了一个大小由 size
指定且值不确定的对象的空间。
返回值
malloc
函数返回一个空指针或指向分配空间的指针。
因此:像下面这样做是否存在非常真实的可能性触发未定义行为?
uint32_t* a = malloc(10*sizeof(uint32_t));
*a = 7;
毕竟,我们无法保证 malloc
的返回值对齐到任何特定值。
英文:
I recently learned that dereferencing a pointer not aligned for a certain object (uint32_t* foo = (uint32_t*)7; *foo = 5;
) is in fact undefined behaviour:
C11 section 6.2.8: Alignment of objects:
> Complete object types have alignment requirements which place
> restrictions on the addresses at which objects of that type may be
> allocated. An alignment is an implementation-defined integer value
> representing the number of bytes between successive addresses at which
> a given object can be allocated. An object type imposes an alignment
> requirement on every object of that type: stricter alignment can be
> requested using the _Alignas
keyword.
Ok, very interesting. But malloc
does not seem to care at all about alignment:
> #### 7.22.3.4 The malloc
function
>
> Synopsis
>
> #include <stdlib.h>
<br/>
> void *malloc(size_t size);
<br/><br/>
> Description
>
> The malloc
function allocates space for an object whose size is
> specified by size and whose value is indeterminate.<br/><br/>
> Returns
>
> The malloc
function returns either a null pointer or a pointer to the allocated space.
Therefore: Is there not a very real chance that doing something like the following invokes undefined behaviour?
uint32_t* a = malloc(10*sizeof(uint32_t));
*a = 7;
We have no guarantee that the return value of malloc
is aligned to anything, after all.
答案1
得分: 8
你似乎在引用关于malloc
函数的部分之前略过了标准的一个段落。根据C17草案标准,并且在C11和其他后续版本的标准中情况基本相同(重点是我加粗的):
7.22.3 内存管理函数
1
aligned_alloc
、calloc
、malloc
和realloc
函数连续调用分配的存储空间的顺序和连续性是未指定的。如果分配成功,返回的指针***适当地对齐,以便可以分配给具有基本对齐要求的任何类型对象的指针,然后用于访问这种对象或在分配的空间中的这种对象的数组(直到明确释放该空间)。分配的对象的生命周期从分配开始到释放结束。每次这样的分配都应产生指向与任何其他对象不相交的对象的指针。返回的指针指向分配空间的起始(最低字节地址)。如果无法分配空间,则返回空指针。如果请求的空间大小为零,则行为是实现定义的:要么返回空指针表示错误,要么行为就像大小是某个非零值一样,但返回的指针不得用于访问对象。
所以,你问题的基本前提是错误的,通过调用malloc
成功返回的指针几乎可以用于几乎任何类型的对象,就其对齐要求而言。对于具有扩展对齐要求的对象情况可能不同,在这种情况下,应使用更具体的分配技术。
英文:
You seem to have skipped a paragraph of the Standard just a tiny bit earlier than the part you quote regarding the malloc
function. From this C17 Draft Standard – and it's much the same in C11 and other, later versions of the Standard (bold emphasis mine):
> #### 7.22.3 Memory management functions<br/>
> 1 The order and contiguity of storage allocated by successive calls to the aligned_alloc
, calloc
,
> malloc
, and realloc
functions is unspecified. The pointer returned if
> the allocation succeeds is suitably aligned so that it may be assigned
> to a pointer to any type of object with a fundamental alignment
> requirement and then used to access such an object or an array of such
> objects in the space allocated (until the space is explicitly
> deallocated). The lifetime of an allocated object extends from the
> allocation until the deallocation. Each such allocation shall yield a
> pointer to an object disjoint from any other object. The pointer
> returned points to the start (lowest byte address) of the allocated
> space. If the space cannot be allocated, a null pointer is returned.
> If the size of the space requested is zero, the behavior is
> implementation-defined: either a null pointer is returned to indicate
> an error, or the behavior is as if the size were some nonzero value,
> except that the returned pointer shall not be used to access an
> object.
So, the basic premise of your question is wrong and a pointer returned by a (successful) call to malloc
will be usable for almost any type of object, in terms of its alignment requirements. The situation may be different for objects that have extended alignment requirements, in which case more specific allocation techniques should be used.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论