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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • C#结合数据库开发通讯录管理系统

    通讯录管理系统,数据库关系模式为:账户(账户名,登录密码,头像),联系人(ID,姓名,电话,QQ,Email)。主要功能包括:注册,登录,注销账号,修改账户名以及密码,更换头像,以及对联系人的增删改查。工具:VisualStudio2015,sqlserver2014数据库关系表:Account:…

    2022年4月6日
    47
  • 超详细的MySQL8.0.20安装教程及其安装问题处理

    超详细的MySQL8.0.20安装教程及其安装问题处理文章目录:官网下载MySQL的安装包添加并配置my.ini文件配置系统变量并初始化MySQL安装并启动MySQLNavicat连接MySQL并修其密码安装过程中常见问题及其解决方法官网下载MySQL的安装包下载链接如下:MySQL8.0.20版本其他版本:MySQL8.0.16版本MySQL8.0.20版本压缩包解压后如下图所示:添加并配置my.ini文件在原解压根…

    2022年4月29日
    41
  • 复试的时候面试官问我还有什么问题(和面试官聊得很好但没有录用)

    我是一名程序员,我的主要编程语言是Java,我更是一名Web开发人员,所以我必须要了解HTTP,所以本篇文章就来带你从HTTP入门到进阶,看完让你有一种恍然大悟、醍醐灌顶的感觉。最初在有网络之前,我们的电脑都是单机的,单机系统是孤立的,我还记得05年前那会儿家里有个电脑,想打电脑游戏还得两个人在一个电脑上玩儿,及其不方便。我就想为什么家里人不让上网,我的同学xxx家里有网,每…

    2022年4月17日
    43
  • pytest运行_python缓存机制

    pytest运行_python缓存机制前言pytest运行完用例之后会生成一个.pytest_cache的缓存文件夹,用于记录用例的ids和上一次失败的用例。方便我们在运行用例的时候加上–lf和–ff参数,快速运行上一

    2022年7月30日
    7
  • linux20个常用命令_常用shell命令

    linux20个常用命令_常用shell命令文章目录Linux_day01ipv4地址服务器Linux_day02Linux的文件目录Linux基本指令一.基础指令1.ls指令:2.pwd命令3.cd命令——改变目录4.mkdir—— 创建目录5.touch指令——创建文件6.cp指令——复制7.mv指令——移动,重命名8.rm指令——移除,删除9.vim指令10.输出重定向11.cat指令二.进阶指令1.df指令——查看磁盘空间2.free指令——查看当前内存的使用情况3.head指令——查看文件的前n行(默认n为10)4.tail指令——查看文件

    2022年8月9日
    2
  • UVA11294-Wedding(2-SAT)

    UVA11294-Wedding(2-SAT)

    2022年1月4日
    35

发表回复

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

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