程序不终止
Program does not terminate
在下面的代码中,当 运行 使用 GNU GCC v8.2.0 时,代码不会终止:
int main(void)
{
/* code */
int myArray[] = {2, 4};
int otherArray[] = {777, 888};
for(int i = 0; i<4; i++)
{
myArray[i] = 0;
cout << "myArray[" << i << "]=";
cout << myArray[i] << endl;
cout << "add: " << &myArray[i] << endl;
}
for(int i = 0; i<2; i++)
{
cout << "otherArray[" << i << "]=";
cout << otherArray[i] << endl;
cout << "add: " << &otherArray[i] << endl;
}
return 0;
}
输出:
add:0x28ff24
myarray[2]=0
add:0x28ff28
myarray[0]=0
add:0x28ff20
myarray[1]=0
add:0x28ff24
myarray[2]=0
add:0x28ff28
myarray[0]=0
add:0x28ff20
myarray[1]=0
add:0x28ff24
myarray[2]=0
add:0x28ff28
myarray[0]=0
add:0x28ff20
myarray[1]=0
add:0x28ff24
myarray[2]=0
add:0x28ff28
myarray[0]=0
add:0x28ff20
myarray[1]^C
for(int i = 0; i<4; i++)
将 'for loop' 中的 4 替换为 2,如下所示:
for(int i = 0; i<2; i++)
由于您使用的是静态数组,因此最好指定固定大小,但最重要的是在尝试通过比较正在处理的索引与数组大小来访问数组时要注意避免这种行为。
您正在通过写入 2 元素数组 myArray
.
的索引 0
-3
来调用未定义的行为
由于这是未定义的行为,因此无法保证如果您将来再次 运行 代码会发生什么或将会发生什么。对您观察到的行为的一个可能解释是,当您编写 myArray[2]
时,它实际上覆盖了 i
的值,导致您的循环在 0
.
处重新启动
简单的解决方案是增大 myArray
或将 for 循环限制更改为 2
。
要检测此类行为,请改用 std::array
并调用具有边界检查功能的 at
函数,当您超出数组边界时将抛出异常。例如:
#include <array>
#include <iostream>
int main(void)
{
/* code */
std::array< int, 2 > myArray = { 2, 4 };
std::array< int, 2 > otherArray = { 777, 888 };
for(int i = 0; i<4; i++)
{
myArray.at(i) = 0;
std::cout << "myArray[" << i << "]=";
std::cout << myArray[i] << "\n";
std::cout << "add: " << &myArray.at(i) << "\n";
}
for(int i = 0; i<2; i++)
{
std::cout << "otherArray[" << i << "]=";
std::cout << otherArray.at(i) << "\n";
std::cout << "add: " << &otherArray.at(i) << "\n";
}
return 0;
}
std::array
还有一个 size()
方法的好处,它也可以让你的代码更安全:
for(int i = 0; i<myArray.size(); i++)
{
myArray.at(i) = 0;
std::cout << "myArray[" << i << "]=";
std::cout << myArray[i] << "\n";
std::cout << "add: " << &myArray.at(i) << "\n";
}
在下面的代码中,当 运行 使用 GNU GCC v8.2.0 时,代码不会终止:
int main(void)
{
/* code */
int myArray[] = {2, 4};
int otherArray[] = {777, 888};
for(int i = 0; i<4; i++)
{
myArray[i] = 0;
cout << "myArray[" << i << "]=";
cout << myArray[i] << endl;
cout << "add: " << &myArray[i] << endl;
}
for(int i = 0; i<2; i++)
{
cout << "otherArray[" << i << "]=";
cout << otherArray[i] << endl;
cout << "add: " << &otherArray[i] << endl;
}
return 0;
}
输出:
add:0x28ff24
myarray[2]=0
add:0x28ff28
myarray[0]=0
add:0x28ff20
myarray[1]=0
add:0x28ff24
myarray[2]=0
add:0x28ff28
myarray[0]=0
add:0x28ff20
myarray[1]=0
add:0x28ff24
myarray[2]=0
add:0x28ff28
myarray[0]=0
add:0x28ff20
myarray[1]=0
add:0x28ff24
myarray[2]=0
add:0x28ff28
myarray[0]=0
add:0x28ff20
myarray[1]^C
for(int i = 0; i<4; i++)
将 'for loop' 中的 4 替换为 2,如下所示:
for(int i = 0; i<2; i++)
由于您使用的是静态数组,因此最好指定固定大小,但最重要的是在尝试通过比较正在处理的索引与数组大小来访问数组时要注意避免这种行为。
您正在通过写入 2 元素数组 myArray
.
0
-3
来调用未定义的行为
由于这是未定义的行为,因此无法保证如果您将来再次 运行 代码会发生什么或将会发生什么。对您观察到的行为的一个可能解释是,当您编写 myArray[2]
时,它实际上覆盖了 i
的值,导致您的循环在 0
.
简单的解决方案是增大 myArray
或将 for 循环限制更改为 2
。
要检测此类行为,请改用 std::array
并调用具有边界检查功能的 at
函数,当您超出数组边界时将抛出异常。例如:
#include <array>
#include <iostream>
int main(void)
{
/* code */
std::array< int, 2 > myArray = { 2, 4 };
std::array< int, 2 > otherArray = { 777, 888 };
for(int i = 0; i<4; i++)
{
myArray.at(i) = 0;
std::cout << "myArray[" << i << "]=";
std::cout << myArray[i] << "\n";
std::cout << "add: " << &myArray.at(i) << "\n";
}
for(int i = 0; i<2; i++)
{
std::cout << "otherArray[" << i << "]=";
std::cout << otherArray.at(i) << "\n";
std::cout << "add: " << &otherArray.at(i) << "\n";
}
return 0;
}
std::array
还有一个 size()
方法的好处,它也可以让你的代码更安全:
for(int i = 0; i<myArray.size(); i++)
{
myArray.at(i) = 0;
std::cout << "myArray[" << i << "]=";
std::cout << myArray[i] << "\n";
std::cout << "add: " << &myArray.at(i) << "\n";
}