c语言 - 为什么在 *int_one 处修改内存不会改变 *int_two 处的内存值?



我写了一段非常简单的C代码:

int main(void) {
void *area = malloc(2 * sizeof(int));
unsigned int *int_one = (unsigned int *) area;
unsigned int *int_two = ((unsigned int *) area) + 3;
*int_two = 4293422034;
*int_one = 2;
printf("%un%un", *int_two, *int_one);
return 0;
}

sizeof(int)在我的机器上4。根据我的理解,地址int_one内存的修改不应该对地址int_two存储的值产生影响吗?

修改*int_one会更改 mem. 地址area的前4个字节(也许不是全部 4 个,但足以保证我期望的结果?(,地址int_two处的整数从整数int_one的最后一个字节开始。

那么,在int_one改变记忆不应该对int_two的记忆产生影响吗? 然而,printf调用分别产生42934220342

我确保使用无符号变量以避免混淆 2s 补码和负值,并为*int_one使用一个小值来保证其最后一个字节的更改(不知道这是否正确?

我没有得到什么?

运算符"+"应用于指针时,会将指针增加n倍于它指向的对象的大小。因此,将int*增加3不会增加 3 个字节,而是增加3*sizeof(int)个字节。

指针算术按指针指向的类型大小进行缩放。(sizeof(unsigned int)在您的情况下(。如果要将地址增加 3 个字节,则需要在添加 3 之前强制转换为(char*),但将其转换为unsigned*指针会违反对齐要求 (6.3.2.3p7( 而导致未定义的行为,取消引用指针会使程序通过违反严格的别名规则 (6.5p7( 而"更加未定义"。

要真正正确地进行这种类型的双关语,您需要使用memcpy(或unions(。

例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
void *area = malloc(2 * sizeof(int));
if(!area) return EXIT_FAILURE;
unsigned int *int_one_p = area;
void *int_two_p = (((char*) area) + 3); /*saving this to an (unsigned*) would be UB*/
memcpy(int_two_p,&(unsigned){4293422034},sizeof(unsigned));
memcpy(int_one_p,&(unsigned){2},sizeof(unsigned));
unsigned one,two;
memcpy(&one,int_one_p, sizeof(one));
memcpy(&two,int_two_p, sizeof(two));
printf("%un%un", two, one);
return 0;
}

相关内容

  • 没有找到相关文章

最新更新