指针偏移在 memset 中不起作用?
Posted
技术标签:
【中文标题】指针偏移在 memset 中不起作用?【英文标题】:pointer offset doesnt work in memset? 【发布时间】:2012-05-11 15:23:17 【问题描述】:普通 C,在 Windows 7 和 HP 机器上。
int main(void)
unsigned int a = 4294967295;
unsigned int *b = &a;
printf("before val: '%u'\n", *b); // expect 4294967295, got 4294967295
memset(b+2, 0, 1);
printf("after val: '%u'\n", *b);
// little endian 4th 3rd 2nd 1st
// expect 4278255615 - 11111111 00000000 11111111 11111111
// got 4294967295 - 11111111 11111111 11111111 11111111
return 0;
我想将整数的第三个字节设置为 0x0,但保持不变。有任何想法吗?谢谢。
在我的机器上,int 是 32 位。
【问题讨论】:
【参考方案1】:指针加/减不会只移动一个字节 - 它会移动被指向对象类型的大小。
也就是说(假设是4字节整数),
int *p = 0x00004
int *q = p+1;
assert(q == 0x00008)
基本上和使用operator的索引是一样的:
int *q = &p[1]
如果要将指针加一,请将其强制转换为 unsigned char *
。您这样做的方式是覆盖不属于变量a
的内存,并且可能会为其他内容覆盖现有数据。
【讨论】:
实际上,除了!= 0
之外,你不能假设任何关于(int*)0 + 1
的信息,因为空指针可能会被特殊处理。
@larsmans bah humbug :P 你也不能假设 NULL 为零 :P 但我改变了我的帖子。干杯,伙计。
对,它以类型的大小递增。一个彻头彻尾的笨蛋。谢谢你。一分钟后接受。
您可以假设0
,在指针上下文中,是空指针。 c-faq.com/null/null2.html(但是+1。)【参考方案2】:
b+2 实际上是两个 int 而不是两个字节的位移。
unsigned int *b = &a;
memset(b+2, 0, 1);
其实你要修改第三个字节
unsigned int *b = &a;
memset( ((char*)b)+2, 0, 1);
【讨论】:
【参考方案3】:int 只保证至少是两个字节,所以如果你想设置第三个字节,你应该使用 long int(或 uint32_t)。无论如何,我会使用按位和运算符来完成
unsigned long a = 4294967293;
/* regular code */
a &= 0xFFFF00FF;
【讨论】:
以上是关于指针偏移在 memset 中不起作用?的主要内容,如果未能解决你的问题,请参考以下文章