【发布时间】:2020-05-15 02:06:08
【问题描述】:
我试图了解如何检查指针是否对齐并最终对齐。
为了理解它,我采用了这个函数:
#define PJ_POOL_ALIGNMENT 8
PJ_DEF(pj_pool_t*) pj_pool_create_on_buf(const char *name,
void *buf,
pj_size_t size)
{
#if PJ_HAS_POOL_ALT_API == 0
struct creation_param param;
pj_size_t align_diff;
PJ_ASSERT_RETURN(buf && size, NULL);
if (!is_initialized) {
if (pool_buf_initialize() != PJ_SUCCESS)
return NULL;
is_initialized = 1;
}
/* Check and align buffer */
align_diff = (pj_size_t)buf;
if (align_diff & (PJ_POOL_ALIGNMENT-1)) {
align_diff &= (PJ_POOL_ALIGNMENT-1);
buf = (void*) (((char*)buf) + align_diff);
size -= align_diff;
}
param.stack_buf = buf;
param.size = size;
pj_thread_local_set(tls, ¶m);
return pj_pool_create_int(&stack_based_factory, name, size, 0,
pj_pool_factory_default_policy.callback);
#else
PJ_UNUSED_ARG(buf);
return pj_pool_create(NULL, name, size, size, NULL);
#endif
}
显然我感兴趣的部分是/*检查和对齐缓冲区*/ 我认为我唯一理解的是:
让我们专注于 if。 这要验证缓冲区是否与 8 字节多地址对齐。如果if的条件没有对齐,则返回0以外的数字,然后进行对齐,否则,也只有一个位为1,跳过IF就足够了。为了获得这个结果,他们将变量 PJ_POOL_ALIGNMENT 设为 7 (0111),然后他们将与分配缓冲区的地址进行 AND。考虑到如果地址不对齐,我想得到一个不是0的数字,操作如下。
0000... 0111 和
xxx。 . . x100
0000... 0100 未对齐
如果最后 3 位中有 1(或更多 1),因此我知道它与 8 字节块不对齐:x AND 1 = 0,则 if 将为真。然后它会进入校正块。
但是 if 块对我来说是模糊的。 可以确认我的推理是否正确并让我理解障碍的人。
【问题讨论】:
-
基本上对齐一个块意味着将其起始地址四舍五入到对齐的下一个倍数。对我来说,这段代码看起来很奇怪。我希望在 if 块中增加一行:
align_diff = PJ_POOL_ALIGNMENT-align_diff;。 -
您的
align_diff计算需要按照上面@Gerhardh 的建议进行更正。您可以在一个语句中计算align_diff,使用无符号类型的 2 的补码否定规则:align_diff = (pj_size_t)(-(pj_size_t)buf) & (PJ_POOL_ALIGNMENT-1);。 -
澄清一下:这是你的代码吗?您是否尝试理解其他人的代码,或者这是您尝试过的,但您想了解为什么它不起作用?
-
不是我的代码,是正在研究的项目的代码:pjsip.org
-
我已将错误报告通过电子邮件发送到项目邮件列表。