我认为这本书对struct LinkedBlock 的定义存在严重错误。让我们稍后再谈,并开始:
什么是开销?
struct ListNode 设计用于存储一个整数,但除了整数之外,每个节点还有两个指针。因此,对于每个节点,您需要分配 1 个整数 + 2 个指针。让我们假设 4 字节整数和 4 字节指针。所以每个节点将需要 4 + 2x4 = 12 个字节。因此,为了存储 1 项真实数据(即 1 个整数),您需要分配 12 个字节。您在指针上浪费了 8 个字节。这 8 个“浪费”的字节称为开销。它们仅用于簿记 - 不用于数据。
但它变得更糟......当分配动态内存时(通常在使用链表时这样做),会有一些额外的开销。分配器可能需要为每个malloc 提供一点额外内存来存储有关malloc 的信息。另一个问题是malloc ed 内存可能与某些固定块大小(例如 16 或 32 字节)对齐,因此如果分配 20 字节,则无法使用剩余的 12 字节 - 它们被浪费了。这就是本书所说的“分配开销”。 “分配开销”取决于系统,但本书假设每个 malloc 有 8 个额外开销字节。
所以现在每个malloc 'ed struct ListNode 占用:
4 个字节的整数
2 个指针 8 个字节
8 字节用于分配开销
总共 20 个字节,其中 4 个字节用于数据,16 个字节用于开销。因此,对于您需要存储的每个整数,您需要 20 个字节。如果你想存储 1000 个整数,你最终会浪费 16kb 的开销来存储 4kb 的数据。
现在回到struct LinkedBlock。在书中它是这样的:
struct LinkedBlock {
struct LinkedBlock *next;
struct LinkedNode *head;
int nodeCount;
};
我很确定书中有一个错误,它应该看起来像这样:
struct LinkedBlock {
struct LinkedBlock *next;
int *dataArray;
int nodeCount;
};
使用方法如下:
struct LinkedBlock pNode = malloc(sizeof(struct LinkedBlock));
pNode->dataArray = malloc( 100 * sizeof(int) );
第一个 malloc 需要 4 + 4 + 4 + 8 = 20 个字节。 (指针、指针、int、分配开销)
第二个malloc 需要 4 * 100 + 8 = 408 字节。 (100 int,分配开销)
所以总共有 428 个字节。
但是,由于malloc'ed 数据可以保存 100 个整数(对应于 400 个字节),因此您的开销只有 28 个字节。换句话说 - 每个整数平均使用 4.28 个字节。将其与每个整数需要 20 个字节的第一种方法进行比较。
为什么他只为 100 个元素的数组声明 8 个字节的开销?
这是因为数组是在一次调用中分配的,并且每个 malloc 调用都假定有 8 个字节的分配开销。