Ser*_*sta 13 c malloc language-lawyer
这是一个可以将char数组与任何数据类型一起使用的后续内容吗?
我知道动态内存和malloc的常见实现,可以在维基百科上找到引用.我也知道malloc返回的指针可以转换成程序员想要的任何东西,甚至没有警告,因为6.3.2.3指针中的标准状态§1
指向void的指针可以转换为指向任何不完整或对象类型的指针.指向任何不完整或对象类型的指针可能会转换为指向void的指针并再次返回; 结果应该等于原始指针.
现在的问题是假设我有没有一个独立的环境malloc和free,我怎么可以建立兼容标准的C的这两个功能的实现?
如果我对标准采取一些自由,很容易:
问题是该实现返回的指针的有效类型仍然是 char *
标准在同一段§7中说明
指向对象或不完整类型的指针可以转换为指向不同对象或不完整类型的指针.如果生成的指针未针对指向类型正确对齐,则行为未定义.否则,当再次转换回来时,结果将等于原始指针.
这似乎不允许我假装被声明为简单字符的内容可以神奇地包含另一种类型,甚至在该数组的不同部分或同一部分中的不同时刻也可以包含不同的类型.不同地解释引用这样的指针似乎是未定义的行为,并严格解释标准.这就是为什么memcpy当你在字符串缓冲区中获得对象的字节表示时,例如当你从网络流中读取它时,常用的习惯用法而不是别名.
那么如何在纯C中构建一个符合malloc的实现呢?
C 标准的作者投入了更多的精力来指定那些不属于 C标准的行为。因为他们期望明智的编译器编写者会支持有用的行为,无论标准是否强制要求它,并且因为迟钝的编译器编写者可以产生“合规”实现完全合规但完全无用(*)。
在 C89 出现之前,可以在许多平台上编写可靠且高效的 malloc() 等效项,并且我认为没有理由相信作者的意图是让人们为能够处理 malloc() 的平台编写 C89 编译器以前的等效物不会使这些实现像它们的前身一样强大。不幸的是,这种在 20 世纪 90 年代流行的语言(它是 C89 及其前身的超集)已被一种低质量的方言所取代,这种方言省略了 C89 的作者认为理所当然的功能,并期望其他人也这样做。
即使除了如何获取内存的问题之外,一个更大的问题是 malloc() 承诺新分配的内存在最坏的情况下将保留不确定值;由于结构类型没有陷阱表示,因此使用结构类型指针读取此类存储将具有已定义的行为。但是,如果内存之前使用某种其他类型写入,则结构类型读取将具有未定义行为,除非 free() 或 malloc() 物理擦除所有相关存储,从而抵消了 malloc( ) 而不仅仅是 calloc()。
(*)假设存在至少一组源文件,实现在没有 UB 的情况下以兼容方式处理,当给定任何其他源文件集时,实现可能需要任意(可能不可能大)量的堆栈空间,并且表现在如果该空间不可用,则任意时尚。