如何调整在C中的指针 [英] How to align a pointer in C

查看:191
本文介绍了如何调整在C中的指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法来调整在C中的指针?假设我正在写数据到​​一个数组堆栈(所以指针变为向下),我想下一个数据我写为4对齐,这样的数据写入是4的倍数的存储位置,会怎么办是什么?

Is there a way to align a pointer in C? Suppose I'm writing data to an array stack (so the pointer goes downward) and I want the next data I write to be 4-aligned so the data is written at a memory location which is a multiple of 4, how would I do that?

 uint8_t ary[1024];
 ary = ary+1024;
 ary -= /* ... */

现在假设的位置点 0×05 。我希望它指向 0×04 。 现在,我可以做

Now suppose that ary points at location 0x05. I want it to point to 0x04. Now I could just do

ary -= (ary % 4);

但C不容许模上的指针。是否有任何解决方案,体系结构无关?

but C doesn't allow modulo on pointers. Is there any solution that is architecture independent?

推荐答案

数组是不会指针,尽管任何你可能已经读过这里被误导的答案(意为特别或计算器,一般这个问题 - 或其他地方)。

Arrays are NOT pointers, despite anything you may have read in misguided answers here (meaning this question in particular or StackOverflow in general — or anywhere else).

您不能改变由数组名psented转口货值为$ P $,如图所示。

You cannot alter the value represented by the name of an array as shown.

什么是混乱的,也许是,如果是一个函数的参数,它就会出现,你可以调整数组:

What is confusing, perhaps, is that if ary is a function parameter, it will appear that you can adjust the array:

void function(uint8_t ary[1024])
{
    ary += 213; // No problem because ary is a uint8_t pointer, not an array
    ...
}

数组作为函数的参数从任一外的函数或函数中定义的数组不同。

Arrays as parameters to functions are different from arrays defined either outside a function or inside a function.

您可以做的:

uint8_t    ary[1024];
uint8_t   *stack = ary + 510;
uintptr_t  addr  = (uintptr_t)stack;

if (addr % 8 != 0)
    addr += 8 - addr % 8;
stack = (uint8_t *)addr;

这确保了堆栈中的值的是一个8字节边界对齐,向上取整。你的问题问的四舍五入到4字节的边界,因此code变为:

This ensures that the value in stack is aligned on an 8-byte boundary, rounded up. Your question asks for rounding down to a 4-byte boundary, so the code changes to:

if (addr % 4 != 0)
    addr -= addr % 4;
stack = (uint8_t *)addr;

是的,你可以做到这一点位掩码太多:

Yes, you can do that with bit masks too:

addr = (addr + (8 - 1)) & -8;  // Round up to 8-byte boundary
addr &= -4;                    // Round down to a 4-byte boundary

这只是正常工作,如果LHS是二的幂 - 不是为任意值。在code与模运算将正常工作的任何(正)模量。

This only works correctly if the LHS is a power of two — not for arbitrary values. The code with modulus operations will work correctly for any (positive) modulus.

另请参阅:解决C语言面试问题内存对齐是难倒我(现在改称的How只使用标准库)来分配对齐的存储空间。

See also: Solve the memory alignment in C interview question that stumped me (now retitled How to allocate aligned memory using only the standard library).

这篇关于如何调整在C中的指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆