我有以下结构:
struct SkipListNode{
void *data; // 8 bytes
uint8_t size; // 1 byte
// 7 bytes padding here...
void *next[1]; // dynamic array, 8 bytes each "cell"
};
我正在使用malloc()
,我分配的空间超过sizeof(SkipListNode)
,因此我正在扩展next[]
数组。
我想避免7 bytes
浪费。我可以完全删除size字段,但是我应该在数组末尾保留单NULL
(8个字节)。然而,这无助于缩小尺寸。
我应该使用__ attribute__((__ packed__))
还是以某种不同的方式来解决这个问题?
这也必须在C和C ++下编译。
编译器是gcc。
答案 0 :(得分:3)
#include <stdio.h>
#include <stdint.h>
struct SkipListNode{
void *data; // 8 bytes
uint8_t size; // 1 byte
void *next[1];
};
struct SkipListNode_pack{
void *data; // 8 bytes
uint8_t size; // 1 byte
void *next[1];
} __attribute__((packed));
int main(int argc, char** argv)
{
printf("%d:%d\n", sizeof(struct SkipListNode), sizeof(struct SkipListNode_pack));
return 0;
}
以上代码的输出:
ishaypeled@arania sandbox]$ ./test
24:17
所以是的,如果你想节省内存,你肯定应该在你的情况下使用__attribute__((packed))
。另一方面,就像@MarioTheSpoon所说 - 它可能会带来性能损失。
我检查填充解决方案,看看你是否可以在特定的机器上承受这种惩罚。我敢打赌,除非你真的对性能至关重要,否则你甚至不会注意到它。
答案 1 :(得分:0)
我接受了另一个答案,
然而,我确实考虑过重构程序,我找到了一种正确的方法,而不知道数组的大小。
如果有人对此感兴趣,那就是:
https://github.com/nmmmnu/HM3/blob/master/skiplist.cc
所以我删除了size
字段并删除了结尾NULL。现在结构已对齐:)
虽然重构,我记得可以使用malloc_usable_size()
来查找已分配块的大小。这是一个沉重的非便携式黑客攻击,但在其他一些情况下可以很好地工作。