C++ 为什么这段代码会在不同的机器上导致不同的行为?

C++ 为什么这段代码会在不同的机器上导致不同的行为?,c++,undefined-behavior,C++,Undefined Behavior,显然,有时这段代码会进入无限循环,有时会终止,有时会出现分段错误,具体取决于机器。为什么行为不一致 void loop() { int x[512]; int i=0; while (i++ <512) { x[i] = 0; } } int main () { printf("\nCalling loop -->>\n"); loop(); } void循环(){ int x[512]; in

显然,有时这段代码会进入无限循环,有时会终止,有时会出现分段错误,具体取决于机器。为什么行为不一致

void loop() {
    int x[512]; 
    int i=0; 
    while (i++ <512) { 
        x[i] = 0; 
    } 
} 
int main () { 
    printf("\nCalling loop -->>\n"); 
    loop(); 
}
void循环(){
int x[512];
int i=0;

而(i++,因为您正在执行后增量。当
i
为511时,它通过了不等式,但随后它增加到512。将
x[512]
赋值给可能是可能不是的内存是访问冲突(它是未定义的)由您的应用程序所有。如评论中所述,您在不同的平台上体验到的行为略有不同,因为此错误会导致所谓的未定义的行为操作不是由C++标准定义的,并且由于<>强>编译器和操作系统具有<强>不同的< /强>底层实现-您得到<强>不同< /强>行为> < /p> ,因为您正在执行<强>后增量< /强>。当<代码> i <代码>为511时,它通过了不等式,但是它是I递增到512。将
x[512]
分配给可能是可能不是的内存是访问冲突(它是未定义的)由您的应用程序所有。如评论中所述,您在不同的平台上体验到的行为略有不同,因为此错误会导致所谓的未定义的行为操作不是由C++标准定义的,并且由于<强>不同的< /强>编译器和操作系统具有<强>不同的<强>基础实现-如果调用未定义的行为(如您所做的),则得到<>强> > 行为。< /p> < p>你会得到未定义的行为-这意味着不同的编译器可以在同一台机器上给出不同的结果,不同机器上的不同编译器可以给出不同的结果;见鬼,一台机器上的单个编译器可以看到月亮的相位,并根据相位决定做不同的事情!它们都是正确的b因为未定义的行为正是-未定义的

如果你得到一个无限循环,很可能是
&x[512]=&i
,当你将零写入
x[512]
(这是未定义的行为)时,你将零
i
,循环继续

如果它崩溃,很可能是
x[512]
与调用堆栈上的一些关键控制信息重合,并且通过践踏返回地址或帧指针,您完全搞糟了系统

但是,无论如何,机器和编译器工作正常;问题出在代码上。循环应该是:

while (i < 512)
    x[i++] = 0;
while(i<512)
x[i++]=0;

如果调用未定义的行为(如您所做)你会得到未定义的行为-这意味着不同的编译器可以在同一台机器上给出不同的结果,不同机器上的不同编译器可以给出不同的结果;见鬼,一台机器上的单个编译器可以看到月亮的相位,并根据相位决定做不同的事情!它们都是正确的b因为未定义的行为正是-未定义的

如果你得到一个无限循环,很可能是
&x[512]=&i
,当你将零写入
x[512]
(这是未定义的行为)时,你将零
i
,循环继续

如果它崩溃,很可能是
x[512]
与调用堆栈上的一些关键控制信息重合,并且通过践踏返回地址或帧指针,您完全搞糟了系统

但是,无论如何,机器和编译器工作正常;问题出在代码上。循环应该是:

while (i < 512)
    x[i++] = 0;
while(i<512)
x[i++]=0;

想象一下,当
i
为511时,无法保证
x[512]=0
会破坏i的值。@cf16未定义的行为只是听起来的样子。它有时会崩溃,因为当你有未定义的行为时会发生这种情况。一切都会发生。(跟我一起唱)它可以工作,它可以崩溃,它可以跳迪斯科舞…@NikBougalis:我说,我们可以在我们想去的地方崩溃,一个他们永远找不到的地方。我们可以表现得像我们从这个世界编写代码一样,把核心文件远远抛在脑后。我们可以崩溃!(向戴帽子的男人道歉…)想象一下
I
是511。不能保证
x[512]=0
会破坏i的值。@cf16未定义的行为就是它听起来的样子。它有时会崩溃,因为当你有未定义的行为时会发生这种情况。一切都会发生。(和我一起唱)它可以工作,它可以崩溃,它可以跳迪斯科舞…@NikBougalis:我说,我们可以在我们想去的地方崩溃,一个他们永远找不到的地方。我们可以表现得像我们从这个世界编写代码一样,把核心文件远远抛在脑后。我们可以崩溃!(向戴帽子的人道歉…)实际上,它可能正在覆盖堆栈上的
i
的值。@EricJ:很可能
i
是在内存中
x
之前分配的,或者(就像我刚才在自己的系统上看到的那样)在
x
i
@EricJ之间存在差距。-这取决于编译器。大约十五年前,微软有一个基本上存在这个问题的示例程序,当它使用编译器编译时,它运行并产生正确的输出。使用Borland的编译器编译它会产生一个崩溃的程序。di区别在于内存中自动对象的布局。实际上,它可能覆盖了堆栈上
i
的值。@EricJ.:很可能
i
是在内存中
x
之前分配的,或者(正如我刚才在自己的系统上看到的那样,
x
i
之间存在差距@EricJ