C 复制int片段后的相等性检查

C 复制int片段后的相等性检查,c,pointers,C,Pointers,众所周知,未初始化的局部变量具有不确定的值,使用它会调用未定义的行为。但是,像使用指针复制片段和随后检查相等性这样的操作是否也会导致未定义的行为 下面的编译和运行都很顺利,但我不确定 #include <stdio.h> #include <string.h> int main() { int p; int q = 1; char *_p = (char *)&p; char *_q = (char *)&q;

众所周知,未初始化的局部变量具有不确定的值,使用它会调用未定义的行为。但是,像使用指针复制片段和随后检查相等性这样的操作是否也会导致未定义的行为

下面的编译和运行都很顺利,但我不确定

#include <stdio.h>
#include <string.h>

int main()
{
    int p;
    int q = 1;

    char *_p = (char *)&p;
    char *_q = (char *)&q;

    size_t n;
    for(n = 0; n < sizeof(int); n++) {
        memcpy(_q++, _p++, sizeof(char));
    }

    if (p == q) {
        printf("Equal!!!\n");
    }

    return 0;
}
#包括
#包括
int main()
{
INTP;
int q=1;
char*_p=(char*)&p;
char*_q=(char*)&q;
尺寸;
对于(n=0;n
您正在将未初始化内存复制到初始化内存上。最终的结果是两个内存位置的内容将是相同的,因此匹配。由于源未初始化,因此无法保证其值;将此值复制到先前初始化的值上后,将清除设置为的内容,并将其替换为未知值

因此他们会匹配


尽管您的复制例程有点过度,但我想您已经意识到了这一点,并纯粹将其用于实验:)

为了跟进@Jonathan,您处理的不是未定义的行为,而是未定义的值。未定义的值可以很好地复制

如果您试图用一个未定义的值(可能是零)除,那么什么是未定义的。更糟糕的是,通过未定义的指针赋值

int *p; int q = 1; char *p = q; int*p; int q=1; char*p=q; 尝试后一种方法,您很可能会分割错误,如果您不这样做,您很可能会在随机记忆位置上行走;通常在小的、短期的程序中没有被注意到,但对于大的、长期的程序来说,这是一个可怕的问题


启用积极的编译器检查可能会捕获简单的情况。更隐晦的情况会带来严重的调试挑战

“在非斜体内存上复制初始化内存”。反过来说。OP正在从未初始化的内存进行复制。这是未定义的行为。哎呀!是的,副本是另一种方式。但是,比较的结果不会是未定义的,因为结果将是两个整数值(尽管未定义)将是彼此的精确副本并匹配。不,这是错误的。一旦遇到UB,编译器可以做任何它喜欢的事情。这些值很可能相同,但仍然是UB,因为没有要求或保证每次实现都会给出相同的结果。为什么将一个内存位置复制到另一个内存位置不会导致两个位置相等?编译器在执行时不参与,这种情况下的代码处理的是指向内存的指针。@Graeme Google使用任何单位化变量或内存的“陷阱表示法”是未定义的行为。由于您是从未初始化的内存进行复制,因此使用该复制结果的任何操作也是未定义的行为。