c - 这个旧的 C 指针数学/宏的东西在做什么?

标签 c pointers macros b-tree isam

我需要帮助来理解一些旧 C 代码中发生的事情。

我正在使用旧的 btree/isam 软件产品(来自 Softfocus)将我的数据写入数据库。它本质上是将数据放入 mydb.dt 文件,将索引数据放入 mydb.nx(例如)。

在我的程序中,我有一个结构,其成员对应于数据库中的“字段”。结构定义如下(我用虚构的数据大大简化了):

typedef struct {
    unsigned char name[50];    /*size is 50 bytes*/
    int active;                /*size is 4 bytes*/
    int yet_unused_bytes[46];  /*unused space (in fixed-length record)*/
} DB_PEOPLE;                   /*total struct size is 100 bytes*/

当我想写入记录时,我会像这样调用数据库软件的 bt3Write 例程(people_db_fd 是我的数据库文件的描述符,db_current_record_people 只是我上面的结构的副本,其中包含数据):

ret = bt3Write(people_db_fd, db_current_record_people);

bt3Write 例程基本上如下(我认为确切地知道它在做什么并不重要,但关键部分是 trueBase 位)。 fd 是数据库文件,data 是字节流(我在上面交给它的 db_current_record_people 结构)。我想 recno 只是我在这里不关心的 nx 文件的一些开销,lioWrite 负责:

/*
 * all the keys are in; write the data record and store a copy
 */
if (lioWrite(fd -> fdData, recno, trueBase(data)) == UERROR)
    return (sfuint) isMuCallErr(BT3WRITE, 0);

在头文件中,trueBaseBASEOFFSET 定义为以下宏:

/*
 *  macro for easing the buffer address calculations (who knows what
 *  may change down the road
 */
#define  BASEOFFSET             (sizeof(sflong))
#define  trueBase(address)      ((char *) address - BASEOFFSET)

现在,这就是我需要帮助的地方(我绝不是 C 语言专家……几乎没有功能,真的)。我需要知道 trueBase 在做什么(或者你最好的猜测)。在我未经训练的眼中,它似乎正在将指向数据的指针移动 BASEOFFSET 的长度(在我的系统上是 8 个字节)。

任何了解此特定软件产品的人都可以获得额外奖励积分!它很旧,我真的找不到任何文档。它的评论相当好 - 除了这一点。

最佳答案

您的分析是正确的。看起来他们在每次分配时都存储了一些隐藏的 header 数据。所以他们只给你一个指向“用户”部分的指针。例如,只有当您必须释放数据时,您才需要知道分配空间的“真实”起点,这就是宏正在计算的内容。

我不申请加分,因为我不知道那是什么。

关于c - 这个旧的 C 指针数学/宏的东西在做什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33178358/

相关文章:

c - 这两个定义有什么区别?

c - *ptr 和 **ptr 有什么区别?

c++ - FOR_EACH 宏在调用宏中有两个或多个参数

macros - 是否可以使用符号宏来获得类似标签的行为?

c - 使用循环计数器命名文件

c - 负整数 >> 31 = -1 不是 1?

c - 验证数组的输入

c - 为什么对于 sqlite3_open 我们使用双指针 ** 而对于 sqlite3_prepare 我们使用指针 *

c++ - 为什么以及何时值得使用指向指针的指针?

c++ - 如何避免 C++ 派生类中基类成员的重复拷贝