2013-11-06 5 views
1

Я пытаюсь узнать, как использовать функции sds. У меня есть файлы кода sds.h и sds.c в папке моего проекта, а небольшая программа разведки, которую я написал, компилируется и работает нормально. Однако мне трудно понять некоторые из того, что я вижу в коде из файлов sds.h и sds.c. Я не могу сказать, почему он компилирует, а тем более работает.Указатели, действительные адреса памяти и понимание библиотеки sds

Код в вопросе:

typedef char *sds; 

struct sdshdr { 
    int len; 
    int free; 
    char buf[]; 
}; 

static inline size_t sdslen(const sds s) { 
    struct sdshdr *sh = (void*)(s-(sizeof(struct sdshdr))); 
    return sh->len; 
} 

sdslen() вызывается несколько раз в файле sds.c, и я могу даже использовать его в своей собственной программе после включения sds.h. Я знаю, что typedef делает sds типом, который является только указателем на char. Ключевое слово static ограничивает область действия функции. Inline означает, что функция будет вставляться в код компилятором, когда она вызывается, а не с использованием механизмов вызова стека и функций. Мне кажется, что указателю * sh в функции sdslen() присваивается адрес памяти sizeof (struct sdshdr) до адреса, хранящегося в s, а затем без инициализации какой-либо из переменных в структуре передается переменная-член len назад. Любая помощь в понимании этого, что действительно происходит, будет оценена по достоинству.

ответ

1

Думаю, что я понял. Ответ в другой функции из sds.c файла:

sds sdsnewlen(const void *init, size_t initlen) { 
    struct sdshdr *sh; 

    if (init) { 
    sh = zmalloc(sizeof(struct sdshdr)+initlen+1); 
    } else { 
    sh = zcalloc(sizeof(struct sdshdr)+initlen+1); 
    } 
    if (sh == NULL) return NULL; 
    sh->len = initlen; 
    sh->free = 0; 
    if (initlen && init) 
    memcpy(sh->buf, init, initlen); 
    sh->buf[initlen] = '\0'; 
    return (char*)sh->buf; 
} 

Когда новый sds создается и инициализируется sdsnewlen() функцией памяти динамически выделяется вся структура и с-строки, но адрес c- строка передается обратно. Если sdslen() были вызваны с переменной sds, которая была назначена с использованием malloc без использования функции sdsnewlen(), это вызовет проблему. Пока переменные sds инициализируются с использованием предоставленных функций, тогда память действительна, переменные-члены инициализированы и переменная sds может использоваться в таких вещах, как printf(), как и любая c-строка.

+0

Это способ представления строк [Length-prefixed] (http://en.wikipedia.org/wiki/String_%28computer_science%29#Length-prefixed). – alexander

Смежные вопросы