快速摘要:
该错误实际上与您要执行的操作无关-实现malloc()
。
修复
使用不会给您带来redefinition of 'myMemory' with a different type 'int [4]' vs 'char [1048576]'
错误的编译器或编译器参数。
完整答案
严格来说,这段代码
int* pMem = (int*)(&myMemory[0]);
是strict aliasing violation,可能违反了C标准的6.3.2.3 Pointers,p7:
指向对象类型的指针可以转换为指向不同对象类型的指针。如果结果指针未针对引用的类型正确对齐,则行为未定义。
您的错误
redefinition of 'myMemory' with a different type 'int [4]' vs 'char [1048576]'
是因为您违反了严格的别名规则。
通常,在C语言中,您不能将并非以某种特定类型开头的内存当作另一种类型,但您始终可以将任何内存视为char
类型。例如,您不能采用char
数组并将其视为int
数组。
这是严格的别名规则。
但是您可以使用int
数组并将其视为char
数组-或signed char
或unsigned char
数组。
即使内存以某种方式从int
开始,但是当您回退并访问它时,您所拥有的只是指向它的char
指针(或void
指针)作为int
,必须根据您所在的平台正确对齐内存。
您的代码可能会或可能不会这样做-您将无法确定直到实际运行它。如果不符合对齐要求,则可能会遇到SIGBUS
或其他问题-like this.
违反这些规则会导致未定义的行为。
但是
在这种情况下,您正在“尝试编写自己的'malloc'库”,并且实现中提供了malloc()
,因此这些规则实际上并不适用因为您要提供 C实现本身的一部分。
为什么?为什么这些规则不适用于C环境本身的实现?
由于7.22.3 Memory management functions,他们无法这样做:
如果分配成功,则返回的指针将进行适当对齐,以便可以将其分配给具有基本对齐要求的任何类型的对象的指针,然后将其用于在分配的空间中访问此类对象或此类对象的数组
您根本无法在严格符合要求的C代码中做到这一点。
由malloc()
(以及calloc()
和...)管理的内存以“ untyped”开头,但是在一致的C代码中不能有这样的“ untyped”内存。使用void *
引用内存怎么办?您无法在符合C代码的void *
指针上进行指针算术运算。而且您将必须执行指针算术来管理内存。因此,您几乎必须使用指向某种类型的指针来管理内存。
而且您不能使用数组来避免这种指针运算,因为这些数组还必须具有具体的类型。
因此,您必须“键入”在malloc()
实现中管理的内存,但是当malloc()
调用将内存传递给调用方时,将违反严格的别名规则
如果您管理自己的存储权,您的malloc()
实现将不会违反 6.3.2.3指针(第7页)的对齐限制。
为什么那么多代码违反这些规则?
因为大多数x86平台编写代码使用的人在未对齐的访问中极度宽容。
本文链接:https://www.f2er.com/3143826.html