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