如何解决指针算术,指向容器末端的指针
如果我具有以下结构作为元数据
typedef struct node
{
int size;
char ch;
char arr[1];
}NODE;
假设arr
指向一个数组,该数组恰好在size
之后精确地分配了NODE* a
个字节,那么如何获得指向该数组末尾的指针? (黄色箭头)
我可以喜欢以下内容吗?我想知道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 举报,一经查实,本站将立刻删除。