Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 在单个字中存储整数和位_C_Memory Management_Malloc - Fatal编程技术网

C 在单个字中存储整数和位

C 在单个字中存储整数和位,c,memory-management,malloc,C,Memory Management,Malloc,我读了一篇文章,在幻灯片7中,它建议在一个单词中存储区域大小和可用性,以节省空间。另一种方法是使用两个字,这是浪费,因为可用性位只需要为0或1 这是给出的解释: 如果块对齐,低阶地址位始终为0 为什么要存储一个始终为-0的位 将其用作分配/自由标志!当读取大小字时,必须屏蔽此位 但我并不真正理解它是如何工作的,以及如何在C中实现它。为什么大小整数的一位总是0?(由Posix指定)应该 返回一个新的内存块;或故障时NULL;返回的指针不是程序中任何其他指针的别名 返回一个适当对齐的内存块。

我读了一篇文章,在幻灯片7中,它建议在一个单词中存储区域大小和可用性,以节省空间。另一种方法是使用两个字,这是浪费,因为可用性位只需要为0或1

这是给出的解释:

  • 如果块对齐,低阶地址位始终为0
  • 为什么要存储一个始终为-0的位
  • 将其用作分配/自由标志!当读取大小字时,必须屏蔽此位

但我并不真正理解它是如何工作的,以及如何在C中实现它。为什么大小整数的一位总是0?

(由Posix指定)应该

  • 返回一个新的内存块;或故障时
    NULL
    ;返回的指针不是程序中任何其他指针的别名
  • 返回一个适当对齐的内存块。对齐约束是特定于编译器、ABI和处理器的。(通常,对齐应该是两个单词)
大小并不总是零。(事实上,它从来都不是零)。您可以将其四舍五入为两个单词的倍数,并将最后一位用作已用/空闲位

但是,
malloc
返回的指针应该适当对齐,例如8字节。因此,它们的底部3位为零,分配给
malloc
-ed区域的字节大小是8字节的倍数(高于传递给
malloc
的请求大小),因此最后3位为零(您可以将最后一位用于其他目的,例如,已用/空闲位)

  • 如果块对齐,低阶地址位始终为0
这是理解这一切的关键。许多CPU要求多字节原语值存储在可被原语中字节数整除的地址:16位原语需要存储在偶数地址;32位
int
s需要存储在可被4整除的地址,以此类推。试图通过对应于奇数地址的指针访问
int
,会导致总线错误


在这样的系统中,
malloc
必须始终返回适合存储给定CPU支持的任何原语的地址。因此,如果CPU支持32位整数,则
malloc
返回的所有地址必须可被
4
整除。这样的地址据说是对齐的。为了符合这一要求,
malloc
实现将程序请求的块在末尾的大小调整为0到3个字节,使其长度可被
4
整除。作为该决定的结果,对齐块地址的最后两位将始终为零。
malloc
的实现可以将这些位用于自己的目的,只要它们在返回结果给调用者之前被“屏蔽掉”。
为什么大小整数的一位总是0?

我明白为什么这让人困惑,但我不认为他们在幻灯片7上是这么说的。他们说低位地址总是0

对象的内存地址与特定边界对齐,这意味着对象与其大小的倍数对齐

因此,64位整数与8字节边界对齐; 0x7fff315470d8

如果指针始终与八字节边界对齐,则低阶三位始终为零。ie:0x816=10002

基本上,只要在解引用指针之前将它们取出,就可以在这些低阶位中粘贴任何需要的内容。在64位的情况下,有3位始终为0,因此可以存储3个“标志”。在这个电源点的情况下,他们说取最低的位并将其用作“已分配”标志。只要分配了内存,就在内存中插入1,在将指针发送给用户时将其屏蔽