包结构/避免填充

时间:2015-06-23 07:07:08

标签: c++ c gcc struct

我有以下结构:

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。

2 个答案:

答案 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()来查找已分配块的大小。这是一个沉重的非便携式黑客攻击,但在其他一些情况下可以很好地工作。