During I read the source code of Redis, I found the following code:
dict *d = zmalloc(sizeof(*d));
After searching a different definition of ‘d’, I realized that the d is the same object defined in the same line. In order to understand what happens, I did some testing:
#include <stdio.h> #include <malloc.h> typedef struct { int x; int y; } dict; int main() { dict *d = malloc(sizeof(*d)); printf("sizeof d: %d, *d: %d, type: %dn", sizeof(d), sizeof(*d), sizeof(dict)); free(d); return 0; }
It works as expected, I don’t understand how does it happen at run time. In order to find the magic, I deassembled the executable file by objdump, and realized that: the sizeof is a compile time operator (Which maybe widely known, but I didn’t know that), and all the sizeof has been calculated during compilation. Here’s the part of objdump result of the executable file:
$ objdump -xsd sizeof_test 00000000004005ac <main>: //save the previous rbp on the stack 4005ac: 55 push %rbp //rbp == stack pointer at the begining 4005ad: 48 89 e5 mov %rsp,%rbp //rbp takes 8 bytes, and the only local variable which is a pointer //also takes 8 bytes, so make room for 16 bytes 4005b0: 48 83 ec 10 sub $0x10,%rsp //want to malloc 8 bytes 4005b4: bf 08 00 00 00 mov $0x8,%edi //call malloc function 4005b9: e8 d2 fe ff ff callq 400490 <malloc@plt> //assigned the returned value from malloc to the first local variable //which is d 4005be: 48 89 45 f8 mov %rax,-0x8(%rbp)