C 为什么';修改*int_一处的内存不会改变*int_二处的内存值吗?
我写了一段非常简单的C代码:C 为什么';修改*int_一处的内存不会改变*int_二处的内存值吗?,c,memory,malloc,C,Memory,Malloc,我写了一段非常简单的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("%u\n%u\n"
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("%u\n%u\n", *int_two, *int_one);
return 0;
}
sizeof(int)
在我的机器上是4
。根据我的理解,地址int\u one
处内存的修改不应该对地址int\u two
处存储的值产生影响吗
修改*int\u one
会更改mem的第一个4
字节。地址区域
(可能不是全部4个,但足以保证我预期的结果?),地址int\u two
处的整数从integerint\u one
的最后一个字节开始
那么,在int\u one
处更改内存不应该对int\u two
处的内存产生影响吗?
然而,printf
调用分别产生4293422034
和2
我确保使用无符号变量来避免2s补码和负值的混淆,并为*int\u one
使用一个小值来保证其最后一个字节的更改(不知道这是否正确?)
我没有得到什么?运算符“+”应用于指针时,会将指针的大小增加到它所指向对象的大小的倍。因此,将
int*
增加3
并不会增加3个字节,而是将3*sizeof(int)
字节增加。运算符“+”应用于指针时,会将指针的大小增加n
倍于它所指向的对象的大小。因此,通过3
增加int*
不会增加3个字节,而是增加3*sizeof(int)
字节。指针算法是根据指针指向的类型的大小进行缩放的。(sizeof(unsigned int)
。如果要将地址增加3个字节,则需要在添加3之前强制转换为(char*)
,但将其转换为无符号*
指针会违反对齐要求()导致未定义的行为,而取消引用指针会违反严格的别名规则,使程序更加“未定义”()
要真正正确地进行这种类型的双关,您需要使用memcpy
(或union
s)
例如:
#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("%u\n%u\n", two, one);
return 0;
}
#包括
#包括
#包括
内部主(空){
void*面积=malloc(2*sizeof(int));
如果(!区域)返回退出失败;
无符号int*int_one_p=面积;
void*int\u two\u p=((字符*)区域)+3);/*将此保存到(未签名*)将是UB*/
memcpy(int_two_p,&(unsigned){4293422034},sizeof(unsigned));
memcpy(int_one_p,&(unsigned){2},sizeof(unsigned));
未签名的一,二;
memcpy(&one,int_one_p,sizeof(one));
memcpy(&two,inttwo,sizeof(two));
printf(“%u\n%u\n”,二,一);
返回0;
}
指针算法根据指针所指向类型的大小进行缩放。(sizeof(unsigned int)
。如果要将地址增加3个字节,则需要在添加3之前强制转换为(char*)
,但将其转换为无符号*
指针会违反对齐要求()导致未定义的行为,而取消引用指针会违反严格的别名规则,使程序更加“未定义”()
要真正正确地进行这种类型的双关,您需要使用memcpy
(或union
s)
例如:
#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("%u\n%u\n", two, one);
return 0;
}
#包括
#包括
#包括
内部主(空){
void*面积=malloc(2*sizeof(int));
如果(!区域)返回退出失败;
无符号int*int_one_p=面积;
void*int\u two\u p=((字符*)区域)+3);/*将此保存到(未签名*)将是UB*/
memcpy(int_two_p,&(unsigned){4293422034},sizeof(unsigned));
memcpy(int_one_p,&(unsigned){2},sizeof(unsigned));
未签名的一,二;
memcpy(&one,int_one_p,sizeof(one));
memcpy(&two,inttwo,sizeof(two));
printf(“%u\n%u\n”,二,一);
返回0;
}
您应该打印这两个指针:printf(“%p%p\n”,int\u-one,int\u-two)
您应该打印这两个指针:printf(“%p%p\n”,int\u-one,int\u-two)
未来可能的读者:将ptr转换为字符,因为其大小保证为1
字节:((未签名字符*)区域)+3
对于未来可能的读者:将ptr转换为字符
,因为其大小保证为1
字节:((无符号字符*)区域)+3