前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >c语言中的offset_c语言中/和%的区别

c语言中的offset_c语言中/和%的区别

作者头像
全栈程序员站长
发布2022-09-23 10:02:07
2.5K0
发布2022-09-23 10:02:07
举报
文章被收录于专栏:全栈程序员必看

大家好,又见面了,我是你们的朋友全栈君。

今天看libPhenom源代码,看到他们使用的JSON解析库参考的是Jansson JSON解析库。于是就去网上查了这个库,找到了官方网站:http://www.digip.org/jansson/。找了一下发现在Github上能够下载源代码,于是下载了源代码来瞅瞅。

看了一会儿发现有一块代码一直看不明白,就比如说如下的代码:

代码语言:javascript
复制
json_t *json_object(void)
{
    json_object_t *object = jsonp_malloc(sizeof(json_object_t));
    if(!object)
        return NULL;

    if (!hashtable_seed) {
        /* Autoseed */
        json_object_seed(0);
    }

    json_init(&object->json, JSON_OBJECT);

    if(hashtable_init(&object->hashtable))
    {
        jsonp_free(object);
        return NULL;
    }

    object->serial = 0;
    object->visited = 0;

    return &object->json;
}

这里在一开始的时候malloc了一块指向struct json_object_t的地址,但是在将指针返回的时候,却并没有将这个分配好内存的指针返回,返回的是内部的一个struct json_t指针。那这样的话,在需要进行回收内存的时候,需要怎么去查找到地址来进行释放呢?

又看了一会儿突然发现了如下的代码:

代码语言:javascript
复制
#define json_to_object(json_)  container_of(json_, json_object_t, json)
代码语言:javascript
复制
#define container_of(ptr_, type_, member_)  \
    ((type_ *)((char *)ptr_ - offsetof(type_, member_)))

一下子就明白了,是通过offsetof这个宏来获取到内部成员在结构体内的偏移量,然后进而来获取整个结构体的地址。

代码语言:javascript
复制
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>

struct test {
    int a;
    char b;
    long c;
    char d;
};

struct test2 {
    char a;
    char b;
    char c;
};

struct test3 {
    char a;
    struct test b;
    int c;
};

int main(int argc, const char * argv[]) {
    printf("struct test: offset a %d\n", (int) offsetof(struct test, a));
    printf("struct test: offset b %d\n", (int) offsetof(struct test, b));
    printf("struct test: offset c %d\n", (int) offsetof(struct test, c));
    printf("struct test: offset d %d\n", (int) offsetof(struct test, d));
    
    printf("struct test2: offset a %d\n", (int) offsetof(struct test2, a));
    printf("struct test2: offset b %d\n", (int) offsetof(struct test2, b));
    printf("struct test2: offset c %d\n", (int) offsetof(struct test2, c));
    
    printf("struct test3: offset a %d\n", (int) offsetof(struct test3, a));
    printf("struct test3: offset b %d\n", (int) offsetof(struct test3, b));
    printf("struct test3: offset c %d\n", (int) offsetof(struct test3, c));
    
    struct test3 * item = (struct test3 *) malloc(sizeof(struct test3) / sizeof(char));
    item->a = 'a';
    item->c = 10;
    struct test * innerItem = &item->b;
    innerItem->a = 1;
    innerItem->b = 1;
    innerItem->c = 1;
    innerItem->d = 1;
    
    struct test3 * compareItem = (struct test3 *) ((char *) innerItem - offsetof(struct test3, b));
    
    if (compareItem == item) {
        printf("equal\n");
    } else {
        printf("not equal\n");
    }
    
    free(item);
    
    return 0;
}

打印结果如下:

代码语言:javascript
复制
struct test: offset a 0
struct test: offset b 4
struct test: offset c 8
struct test: offset d 16
struct test2: offset a 0
struct test2: offset b 1
struct test2: offset c 2
struct test3: offset a 0
struct test3: offset b 8
struct test3: offset c 32
equal
Program ended with exit code: 0

这里struct test里面成员b和c之间偏移量为4是因为结构体将成员的存放地址对齐了。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/172086.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档