【问题标题】:Since the result of malloc is not guaranteed to be aligned to anything, is it even usable?由于 malloc 的结果不能保证与任何东西对齐,它是否可用?
【发布时间】:2023-01-09 18:15:56
【问题描述】:

我最近了解到,取消引用未针对特定对象 (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 函数为大小为的对象分配空间 由大小指定,其值不确定。退货

malloc 函数返回空指针或指向 分配的空间。

因此:是否真的没有机会做类似的事情

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

调用未定义的行为?毕竟,我们无法保证 malloc 的返回值与任何内容对齐。

【问题讨论】:

  • 不,*alloc 函数返回与最大可能对象(通常为 64 或 128 位)对齐的内存。

标签: c malloc alignment language-lawyer


【解决方案1】:

您似乎跳过了标准的一段,比您引用的有关 malloc 函数的部分早了一点点。来自 this C17 Draft Standard – 在 C11 和标准的其他更高版本中大致相同(粗体强调我的):

7.22.3 内存管理函数

1 通过连续调用 aligned_alloccallocmallocrealloc 函数未指定。指针返回如果 分配成功适当对齐,以便可以分配 指向具有基本对齐方式的任何类型对象的指针 要求然后用于访问这样的对象或这样的数组 分配空间中的对象(直到空间被明确 释放)。分配对象的生命周期从 分配直到解除分配。每个这样的分配应产生一个 指向与任何其他对象不相交的对象的指针。指针 返回指向分配的开始(最低字节地址) 空间。如果无法分配空间,则返回一个空指针。 如果请求的空间大小为零,则行为是 实现定义:要么返回一个空指针来指示 一个错误,或者行为就像大小是某个非零值一样, 除了返回的指针不得用于访问 目的。

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

【讨论】:

  • @Cheiron 好的,我删除了那个词 - 它曾是有点居高临下,我承认。 ;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-09-25
  • 1970-01-01
  • 2018-08-05
  • 1970-01-01
  • 2011-08-04
  • 1970-01-01
  • 2016-03-30
相关资源
最近更新 更多