堆栈粉碎终止程序
stack smashing terminates program
我正在学习 C++,任务是创建一个允许用户修改包含 10 个整数的数组的程序。如果用户给出超出范围的索引,程序将退出。程序适用于负数和范围内的所有数字。当我输入一个超出范围的数字,如 10,我得到:
* stack smashing detected *: terminated
我是新手,如有任何帮助,我们将不胜感激。
#include <iostream>
#include <array>
using namespace std;
int main()
{
array<int, 10> myData; // creates array size 10
int i = 0;
int v = 0;
for (unsigned int n = 0; n < myData.size(); n++) // makes all elements 1
{
myData[n] = 1;
}
do
{
for (unsigned int a = 0; a < myData.size(); a++)
{
cout << myData[a] << " ";
}
cout << endl << "Input index: ";
cin >> i;
cout << endl << "Input value: ";
cin >> v;
myData[i] = v;
} while (i >= 0 && i < myData.size());
{
cout << endl << "Index out of range: Exit " << endl;
}
return 0;
}
当我运行程序时,我得到这个:
1 1 1 1 1 1 1 1 1 1
Input index: 10
Input value: 4
Index out of range: Exit
*** stack smashing detected ***: <unknown> terminated
[1] 56 abort (core dumped) ./edit
您正在访问不属于您的数组的内存,因此出现该错误消息。在使用下标运算符 [].
分配值之前,您应该首先验证索引
这是导致问题的代码片段(评论):
cin >> v;
myData[i] = v; // Direct assignment without validating i
// i needs to be validated before this assignment
有几点我想指出:
对于相同值的初始化,您不需要循环,因为 std::array::fill() 成员函数正是这样做的。
示例:
std::array<int, 10> data;
data.fill( 1 );
您正在使用这样的 std::array
that means you are at least using C++11. So, for array traversals, you can use C++11's range-for 循环:
for ( const auto& i : data )
{
std::cout << i << ' ';
}
如果您还不熟悉,您可能想看看 auto specifier。
我不知道你使用 do-while
loop here. You can use a simple while
无限循环的理由( 用于学习目的 )使用 if-else
在无效索引输入上打破它赋值前验证索引。
例如:
while ( true )
{
// Print array here...
std::cin >> index;
if ( /* index is out of bounds */ )
{
std::cerr << "ERROR: Out-of-range index!\n";
break; // Exit from loop here on invalid index
}
else
{
std::cin >> value;
data[ index ] = value;
}
}
请查看 std::array::at()
执行边界检查并在违反时抛出异常的成员函数。
我不确定你在这部分做什么,因为 std::cout
周围的大括号在这里是多余的:
while(i >= 0 && i < myData.size()); // do-while ends here
{
cout << endl <<"Index out of range: Exit "<< endl;
}
也许,您混淆了 do-while
和 while
循环。
以后请不要忘记格式化您的代码。使用 IDE 的代码格式化功能,或者在 SO 上发布代码时也可以使用任何在线代码格式化站点(例如 http://format.krzaq.cc/)。谢谢!
我正在学习 C++,任务是创建一个允许用户修改包含 10 个整数的数组的程序。如果用户给出超出范围的索引,程序将退出。程序适用于负数和范围内的所有数字。当我输入一个超出范围的数字,如 10,我得到:
* stack smashing detected *: terminated
我是新手,如有任何帮助,我们将不胜感激。
#include <iostream>
#include <array>
using namespace std;
int main()
{
array<int, 10> myData; // creates array size 10
int i = 0;
int v = 0;
for (unsigned int n = 0; n < myData.size(); n++) // makes all elements 1
{
myData[n] = 1;
}
do
{
for (unsigned int a = 0; a < myData.size(); a++)
{
cout << myData[a] << " ";
}
cout << endl << "Input index: ";
cin >> i;
cout << endl << "Input value: ";
cin >> v;
myData[i] = v;
} while (i >= 0 && i < myData.size());
{
cout << endl << "Index out of range: Exit " << endl;
}
return 0;
}
当我运行程序时,我得到这个:
1 1 1 1 1 1 1 1 1 1
Input index: 10
Input value: 4
Index out of range: Exit
*** stack smashing detected ***: <unknown> terminated
[1] 56 abort (core dumped) ./edit
您正在访问不属于您的数组的内存,因此出现该错误消息。在使用下标运算符 [].
分配值之前,您应该首先验证索引这是导致问题的代码片段(评论):
cin >> v;
myData[i] = v; // Direct assignment without validating i
// i needs to be validated before this assignment
有几点我想指出:
对于相同值的初始化,您不需要循环,因为 std::array::fill() 成员函数正是这样做的。
示例:
std::array<int, 10> data;
data.fill( 1 );
您正在使用这样的 std::array
that means you are at least using C++11. So, for array traversals, you can use C++11's range-for 循环:
for ( const auto& i : data )
{
std::cout << i << ' ';
}
如果您还不熟悉,您可能想看看 auto specifier。
我不知道你使用 do-while
loop here. You can use a simple while
无限循环的理由( 用于学习目的 )使用 if-else
在无效索引输入上打破它赋值前验证索引。
例如:
while ( true )
{
// Print array here...
std::cin >> index;
if ( /* index is out of bounds */ )
{
std::cerr << "ERROR: Out-of-range index!\n";
break; // Exit from loop here on invalid index
}
else
{
std::cin >> value;
data[ index ] = value;
}
}
请查看 std::array::at()
执行边界检查并在违反时抛出异常的成员函数。
我不确定你在这部分做什么,因为 std::cout
周围的大括号在这里是多余的:
while(i >= 0 && i < myData.size()); // do-while ends here
{
cout << endl <<"Index out of range: Exit "<< endl;
}
也许,您混淆了 do-while
和 while
循环。
以后请不要忘记格式化您的代码。使用 IDE 的代码格式化功能,或者在 SO 上发布代码时也可以使用任何在线代码格式化站点(例如 http://format.krzaq.cc/)。谢谢!