pack struct / avoid padding

2019-08-11 18:05发布

I have following 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"
};

I am using malloc() and I am allocating more space than sizeof(SkipListNode), so I am extending the next[] array.

I want to avoid 7 bytes waste. I can completely remove size field, but then I should keep single NULL (8 bytes) at the end of the array. However this does not help reducing the size.

Shall I use __ attribute__((__ packed__)) or there some different way I could do the trick?

This must be compiled under C and C++ as well.

Compiler is gcc.

标签: c++ c gcc struct
2条回答
聊天终结者
2楼-- · 2019-08-11 18:24
#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;
}

The output from the above code:
ishaypeled@arania sandbox]$ ./test
24:17

So yeah, you should definitely use __attribute__((packed)) in your case if you want to save memory. On the other hand, like @MarioTheSpoon states - it may come with a performance penalty.

I'd check the padding solution to see if you can live with that penalty on your specific machines. My bet is you won't even notice it unless you're really performance critical.

查看更多
家丑人穷心不美
3楼-- · 2019-08-11 18:28

I accepted the other answer,

however, I did considered refactoring of the program, I found a way to proceed correctly, without knowing the size of the array.

If anyone is interested here it is:
https://github.com/nmmmnu/HM3/blob/master/skiplist.cc

So I eliminated the size field and I eliminated the end NULL. Now the struct is aligned :)

While refactor, I remember that one may use malloc_usable_size() to find the size of allocated block. This is heavy non-portable hack, but could work well at some other cases.

查看更多
登录 后发表回答