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

c语言中的offset_c语言中/和%的区别今天看libPhenom源代码,看到他们使用的JSON解析库参考的是JanssonJSON解析库。于是就去网上查了这个库,找到了官方网站:http://www.digip.org/jansson/。找了一下发现在Github上能够下载源代码,于是下载了源代码来瞅瞅。    看了一会儿发现有一块代码一直看不明白,就比如说如下的代码:json_t*json_object(void)

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

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

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

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指针。那这样的话,在需要进行回收内存的时候,需要怎么去查找到地址来进行释放呢?

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

#define json_to_object(json_)  container_of(json_, json_object_t, json)

#define container_of(ptr_, type_, member_)  \
    ((type_ *)((char *)ptr_ - offsetof(type_, member_)))

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

#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;
}

         打印结果如下:

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.net/172086.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 如何使用keil 5 编写 51单片机 工程

    如何使用keil 5 编写 51单片机 工程目前我们通常编写51程序使用的是keil4,而好多编写STM32等单片机程序的使用keil5。那么如何在keil5中兼容51和STM32程序编写,省去切换版本的繁琐呢?很简单只需两步就可以完成。下面这个方法针对已破解keil5的stm32等一系列。这个肯定是最常见的,因为破解keil5然后编写32工程的教程一大把。1、首先下载编写51的相关东西。可以在官网上下载,例如百度keil官

    2022年5月24日
    48
  • 如何安装Java?

    如何安装Java?在本文中,我们将研究如何安装Java,在Windows操作系统中安装Java,如何检查已安装的版本以及设置环境变量。因此,让我们开始吧。如何安装Java?Java支持许多平台,例如Windows,Linux,Solaris等。这些平台具有自己的安装方法。在本教程中,我们将介绍32位和64位OS的安装过程Windows操作系统。Windows操作系统中的Java安装在Windows操作系统中,32位和64位Windows操作系统都具有类似的Java安装方式。主要区别在于它们的安装软件包。如何检查主机

    2022年7月9日
    22
  • vue动态生成表单_vue element 表单验证

    vue动态生成表单_vue element 表单验证前几天接了一个需求,需要动态生成一个表单数据,然后提交,提交完数据后。通过编辑按钮进入时,需要进行数据回填。没生成表单前的状态单机生成表单生成表单根据选择方式展示不同的表单元素如果从编辑页进入该页面有数据的话,进行数据回填样式同第三点相似,这里不再说明思路:请输入标题,请选择类型为父组件;请选择方式为子组件;根据请选择方式出来的内容为孙子组件难…

    2025年6月11日
    3
  • oracle 协议适配器错误,无法登陆

    oracle 协议适配器错误,无法登陆问题:   之前装好了oracleXE(快捷版),然后关闭此版本所有服务,再装上了oracle11g正式版,使用正式版正常。   关闭正式版的所有服务,打开xe版服务后,从sqlplus登陆,提示oracle 协议适配器错误,无法登陆。    解决:  进入sqlplus前,在commandline下输setoracle_sid=XXXX

    2022年6月22日
    30
  • 利用iframe技巧获取訪问者qq

    利用iframe技巧获取訪问者qq

    2021年12月9日
    56
  • 如何通过异业联盟会员体系赋能实体商家?完善消费者的会员权益[通俗易懂]

    如何通过异业联盟会员体系赋能实体商家?完善消费者的会员权益[通俗易懂]2015年房地产行业进入白银时代,市场竞争异常剧烈,目前有万达、大禹加州湾、宏泰第一城等诸多项目,那类似的行业怎样在这激烈的市场竞争中立于不败之地?怎样才能占据更多的市场份额?怎样才能以更少的投入取得更大的回报?需要解决以上种种问题难吗?也未必难,今天向大家提出更好的方案和方法:异业联盟。异业联盟的好处1、对企业来讲可以让客户资源从10变成100甚至1000这也是资源整合,资源营销的核心。2、减少广告费用的投入,而把一部分广告的费用转嫁给消费者,为消费者省钱,符合“客

    2022年6月29日
    32

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号