究竟什么是“位填充”或“填充位”?

时间:2019-10-17 14:48:07

标签: c++ c memory memory-management padding

我不想骚扰您,但我只是无法在Internet上的任何地方找到关于“位填充”实际上是什么的详尽说明,也找不到与位填充相关的线程的任何答案。在StackOverflow上。

我还搜索了ISO 9899-1990,其中提到了“位填充”,但由于我需要而未作详细解释。

我在网络上发现的与此有关的唯一内容是here,其中仅对一个句子给出了一个荒谬的简短解释,说:

  

位填充:

     

位填充是向传输或存储单元添加一个或多个额外的位,以使其符合标准大小。

     

某些来源将位填充标识为bit stuffing的类型。

至少提供了某种信息,但对我来说却不足。我不太明白那是什么意思。它也指术语 "bit stuffing"


当我在StockOverflow上查看“ padding”的相对标签时,填充被描述为:

  

插入内存结构以实现地址对齐的额外空间-或-框架与HTML元素内容之间的额外空间-或-使用格式化打印命令(如C中的printf)打印出值时,额外的空间或零*-功能家族。

背景:

我经常在数据类型方面找到术语“位填充”,但不了解它是什么,也不了解这些内容。

非常感谢您提供任何基于主题的答案。

4 个答案:

答案 0 :(得分:3)

  

我经常在数据类型方面找到术语“位填充”,但不了解它是什么,也不了解这些内容。

要点是它们是“浪费”的空间。我之所以说“浪费”是因为具有填充位可以使对象更大,但可以使对象的工作变得更加轻松(这意味着更快),而空间浪费也可以带来巨大的性能提升。在某些情况下,这很重要,因为CPU无法处理该大小的对象。

让我们说您有一个类似的结构(所有数字仅是示例,不同的平台可以具有不同的值):

struct foo
{
    short a; // 16 bits
    char  b; // 8 bits 
};

,您正在使用的计算机将在一次读取操作中读取32位数据。读取单个foo并不是问题,因为整个对象都适合该32位块。确实成为问题的是当您拥有数组时。关于数组要记住的重要一点是它们是连续的,元素之间没有空格。它只是一个对象,紧随其后。因此,如果您有一个类似

的数组
foo array[10]{};

因此,第一个foo对象位于32位存储桶中。不过,数组的下一个元素将位于第一个32位存储桶和第二个32位存储桶中。这意味着成员a位于两个单独的存储桶中。如果您尝试执行此操作,则某些处理器可能会这样做(需要付费),而其他处理器则会崩溃。为了解决这两个问题,编译器将在foo的末尾添加填充位以填充其大小。这意味着foo实际上变成了

struct foo
{
    short a; // 16 bits
    char  b; // 8 bits 
    char  _; // 8 bits of padding
};

现在,处理器可以很容易地自己处理foo对象或数组中的对象。它不需要做任何额外的工作,并且每个对象仅添加了8位。您可能需要很多对象才能在现代计算机上开始发挥作用。

有时候,由于访问不对齐,您需要在类型的成员之间进行填充。可以说你有

struct bar
{
    char c; // 8 bits
    int  d; // 32 bits
};

现在bar的宽度为40位,并且d的使用频率更高,因此不会再次存储在两个不同的位置。为了解决这个问题,编译器在cd之类的

之间添加了填充位
struct bar
{
    char    c; // 8 bits
    char _[3]; // 24 bits
    int     d; // 32 bits
};

现在保证d会进入一个32位存储桶。

答案 1 :(得分:1)

  

位填充:
  位填充是向传输或存储单元添加一个或多个额外的位,以使其符合标准大小。

由于您发布的定义已经正确,所以我将尝试通过一个示例进行解释:

假设您必须存储占用少于32位的数据,但是有4个字节的插槽。通过访问每个插槽可以更轻松地访问该数据,因此您只需完成所有32位。完成“给定空间”所需的其他附加位(不是数据的一部分)符合位填充。

我确信在多种情况下可能会有更好的例子。任何人都可以随时使用新的改进或示例来编辑和/或完成答案。

希望这会有所帮助!

答案 2 :(得分:1)

因此,假设您有一个8位数字,它是一个uint8_t,其值设置为4。这可能会存储为a = 0000 0100。现在,假设您希望将其转换为16位数字。会发生什么?您必须为该数字中的“新”位分配一些值。您将如何分配它们?您不能随机分配零或一,原始变量的值将更改。根据架构等情况,您必须填充以增加额外的价值。在我的情况下,这意味着在原始MSB(最高有效位)之前再添加八个额外的零,使我们的数字为a = 0000 0000 0000 0100

值仍然为4,但是现在您可以在[0,2 ^ 16)范围内分配任何内容,而不是[0,2 ^ 8)范围。

答案 3 :(得分:0)

位填充可以在多种情况下使用。网络和加密是两个常见的示例。我相信加密上下文更相关。

在加密中使用填充,使解密消息变得更加困难,因为消息具有共同的部分。如果已知多个消息具有相同的前缀(例如“ hello”),则使破解密钥变得更加容易。通过使用可变长度的位字段“填充”消息,将使破解密钥变得更加困难。

被告知,英国情报部门能够加快对Enigma消息的分析速度,因为德国人以相同的标题开始他们的消息。

要获得更准确的技术描述:https://en.wikipedia.org/wiki/Padding_(cryptography)查找有关块密码和位填充的部分