【问题标题】:stack smashing terminates program堆栈粉碎终止程序
【发布时间】:2018-09-15 03:42:20
【问题描述】:

我正在学习 C++,并被赋予创建一个程序的任务,该程序允许用户修改其中包含 10 个整数的数组。如果用户给出的索引超出范围程序将退出。程序适用于负数和范围内的所有数字。当我输入一个高于我得到的范围的 10 之类的数字时:

* 检测到堆栈破坏 *:已终止

我是新手,任何帮助将不胜感激。

#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 &gt;&gt; i。太好了,您已输入“11”。下一步:myData[i] = v;——太好了,你现在已经破坏了内存。您究竟在哪里做任何检查以确保输入的 i 值在范围内?是的,那部分稍后会出现,但我担心那匹马已经离开了谷仓,那时你已经破坏了记忆。你不能指望以随机的顺序做事,让计算机把事情整理出来,按正确的顺序做事。在您实际尝试访问数组 之前检查越界索引,而不是之后。跨度>

标签: c++ arrays for-loop do-while stack-smash


【解决方案1】:

您正在访问不属于您的数组的内存,因此该错误消息。在使用下标运算符 [] 分配值之前,您应该首先验证索引。

这是导致问题的代码 sn-p(注释):

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,这意味着您至少在使用 C++11。因此,对于数组遍历,您可以像这样使用 C++11 的 range-for 循环:

for ( const auto& i : data )
{
    std::cout << i << ' ';
}

如果您还不熟悉 auto specifier,可能需要查看它。

我不知道你在这里使用do-while 循环的原因。您可以使用简单的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-whilewhile 循环混淆了。


以后请不要忘记格式化您的代码。使用您的 IDE 的代码格式化功能,或者您也可以使用任何在线代码格式化网站(例如http://format.krzaq.cc/),同时在 SO 上发布您的代码。谢谢!

【讨论】:

  • 非常感谢您给我详细的回复。这帮助我更多地理解它。非常感谢。
  • @JovannyElias:不客气!很高兴它有帮助。在使用语言和标准库功能之前,请养成阅读 (C++ Reference)[en.cppreference.com] 的习惯。这将帮助您加快步伐。祝你好运!
猜你喜欢
  • 2021-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多