微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

指针算术,指向容器末端的指针

如何解决指针算术,指向容器末端的指针

如果我具有以下结构作为元数据

typedef struct node
{
    int size;
    char ch;
    char arr[1];
}NODE;

假设arr指向一个数组,该数组恰好在size之后精确地分配了NODE* a 个字节,那么如何获得指向该数组末尾的指针? (黄色箭头)

enter image description here

我可以喜欢以下内容吗?我想知道a+size是否以字节计?

NODE* a;
//some code for memory allocation
NODE* new; // I want this points to the yellow place
new = (NODE*)(a+sizeof(NODE)+size);

解决方法

a上的指针算术将以sizeof(NODE)为单位进行。要指向该区域之后的size字节,应先将a强制转换为char *,以便指针算术一次工作一个字节:

new = (NODE*)((char *)a+sizeof(NODE)+size);

此外,对于您正在做的事情,实际上应该像这样定义NODE

typedef struct node
{
    int size;
    char ch;
    char arr[];
}NODE;

这是声明灵活数组成员的现代方法。您也不必担心arr[0]与额外分配的空间之间的填充字节。

还请注意,遍历NODE的数组不能使用简单的数组表示法。您必须按顺序查看每个节点,才能知道一个节点在哪里结束,下一个节点在哪里开始。

,

在现代C语言中:

typedef struct node
{
    size_t size;
    char ch;
    char arr[];
}NODE;

NODE *allocateNODE(size_t size)
{
    NODE *node = malloc(sizeof(*node) + size * sizeof(node -> arr[0]));

    if(node)
    {
        node -> size = size;
    }
    return node;
}

然后您可以通过以下方式简单地访问arr的元素

node -> arr[x]node -> arr + x

或如果您想要指针算术: (char *)node + offsetof(NODE,arr) + x;

,

抱歉,您不能假设arr指向某个位置,因为arr不是指针,而是数组。您已经声明了一个 one 元素数组,但声明了一个数组,仅此而已。如果需要指针,请使用指针符号,将arr声明为:

    char *arr;

,然后将其初始化为:

typedef struct node
{
    int size;
    char ch;
    char *arr;
}NODE;

/* ... */

    NODE *p = malloc(sizeof *p + NUM_CHARS_YOU_WANT + 1); /* 1 more for a '\0' */
    p->arr = (char *)(p + 1);  /* <-- THIS IS THE TRICK!!! */

您的代码中的错误是认为p + n将是指向n个char位置的指针,该指针比p更远。但是p是指向NODE的指针,p + 1指向下一个元素,如果您认为它是一个数组(指针算术)。因此,诀窍是将指针进一步移动一步,然后将其强制转换为最终类型。

注意

我看到过有人在争论使用char arr[];表示法。只是说该符号可以被标准的承诺者采用最新的C定义,但是与在将指针定义为char *arr;char arr[];之间的传统对等冲突(这种对等仍然保留在参数声明),如果您使用该表示法,则表示@dbush在其响应中保留的内容,您将具有等效的代码,但是您无法初始化arr(如上所述),因为数组不能用作一个左值可为其分配其他地址。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。