C 为什么';修改*int_一处的内存不会改变*int_二处的内存值吗?

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"

我写了一段非常简单的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_two, *int_one);

    return 0;
}
sizeof(int)
在我的机器上是
4
。根据我的理解,地址
int\u one
处内存的修改不应该对地址
int\u two
处存储的值产生影响吗

修改
*int\u one
会更改mem的第一个
4
字节。地址
区域
(可能不是全部4个,但足以保证我预期的结果?),地址
int\u two
处的整数从integer
int\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