gpt4 book ai didi

c - 将结构指针增加一半的结构大小

转载 作者:行者123 更新时间:2023-12-05 02:25:14 25 4
gpt4 key购买 nike

我刚遇到一个有趣的问题需要解决,但我看不到解决它的巧妙方法。

我有两个表示复杂图的基本数据结构,声明如下:

typedef struct _node_t node_t;
typedef struct _graph_t graph_t;

struct {
/* Data fields omitted */
node_t * pNextByLevel;
node_t * pNextByProximity;
node_t * pNextByRank;
} node_t;

struct {
/* Data fields omitted */
size_t nNodes;
size_t nMaxNodes;
node_t * pFirstByLevel;
node_t * pFirstByProximity;
node_t * pFirstByRank;
} graph_t;

实际节点紧跟在标题之后,因此通常使用“graph_t”创建

graph_t * pNewBuffer = calloc(1, sizeof(graph_t) + nMaxNodes * sizeof(node_t));
pNewBuffer->nMaxNodes = nMaxNodes;

并且“原始”节点数组使用

访问
node_t * pNewBufferNodes = (node_t *) &pNewBuffer[1];

现在,有一个支持函数在减少节点数量的缓冲区上运行。它看起来像这样:

status_t reduce(graph_t** ppBuffer)
{
graph_t * pReplacement, * pOld = *ppBuffer;
size_t nRequired;
node_t * oldBuffer = (node_t *) &pOld[1];

/* complex calculation ultimately computes 'nRequired' */

pReplacement = realloc(pOld, sizeof(graph_t) + nRequired * sizeof(node_t));

if ( pReplacement != pOld )
{
int i;
node_t * newBuffer = (node_t *) &pReplacement[1];
ptrdiff_t offset = newBuffer - oldBuffer;

for ( i = 0; i < requiredNodes; i++ )
{
newBuffer[i].pFirstByLevel += offset;
newBuffer[i].pFirstBySimilarity += offset;
newBuffer[i].pFirstByRank += offset;
}
*ppBuffer = pReplacement;
}
}

现在,这已经运行了很长时间了。上面的任何错误都是因为我是凭内存写的,我只是想解释一下这个想法。

现在让我感到困惑的是,当使用新模块的缩减功能时,输入没有“正确”对齐。当我检查地址时,我注意到以下属性:

 ((char *) newBuffer - (char *) oldBuffer) % sizeof(graph_t) == 0
((size_t) newBuffer) % sizeof(node_t) == 0
((size_t) oldBuffer) % sizeof(node_t) == 0
((char *) newBuffer - (char *) oldBuffer) % sizeof(node_t) == sizeof(node_t) / 2

当然,这会导致一些问题,因为“偏移”值变得不正确,但它并不那么明显,因为数据结构的所有其他使用都有效(没有“真正的”对齐问题)。

这归结为我的问题 - 当偏移量不能表示为元素的整数时,您是否看到一种递增指针的巧妙方法?

找到不求助于过度转换的方法的加分点:)

最佳答案

关于 ptrdiff_t :“这是两个指针之间的减法运算返回的类型。这是一个带符号的整数类型,因此可以转换为兼容的基本数据类型。两个指针的减法只允许有一个指向同一数组元素(或数组中最后一个元素的指针)的有效定义值。对于其他值,行为取决于系统特性和编译器实现。”

当你使用 realloc 时,你不是这种情况。所以你的偏移量不会是一个整数。这解释了你的问题。

没有奖励积分的解决方案是将您的指针转换为 char* 来计算偏移量。您最终将得到一个以字节为单位的偏移量。然后您可以使用强制转换添加字节偏移量。为了最大限度地减少转换,您可以编写一个辅助函数,为您的节点指针设置正确的值。

如果您想使用 realloc,我看不到其他解决方案,因为您的初始数组已被 realloc 释放。字节偏移似乎是唯一的方法。

您可以调用缩减数组,复制节点,然后释放旧数组。但是当重新分配就地完成时,您将失去 realloc 的优势。

其他解决方案迫使您更改数据结构。您可以使用 malloc 独立分配您的节点,并且减少更简单。您只需释放不再需要的节点。这似乎是最干净的方法,但你必须重构......

希望对你有所帮助。告诉我,如果我误解了...

关于c - 将结构指针增加一半的结构大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1110050/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com