数组导致堆栈溢出错误

时间:2015-01-31 10:33:37

标签: c++ stack-overflow

我的节目是这样的:

#include<iostream>
#include<fstream>
using namespace std;
int main()
{
  char choice;
  int o,i,marks[i],ttlcredit=0;
  double ttlGPA=0,finalGPA=0,credit[7][2],clsavg;

  cout<<"Please enter what you want to calculate"<<endl;
  cout<<"A for calculating Class Average GPA"<<endl;
  cout<<"B for calculating a Specific GPA"<<endl;
  cout<<"Your choice is? ";
  cin>>choice;
  cout<<endl;

  if (choice == 'A'||choice == 'a')
    {
        cout<<"=========================================="<<endl;
        cout<<"           Class Average GPA"<<endl;
        cout<<"=========================================="<<endl<<endl;
        cout<<"Please enter the number of students in the class: ";
        cin>>number;

         for(i=0;i<number;i++)
        {
            cout<<"\nEnter student #"<<i+1<<"'s marks: ";
            cin>>marks[i];

            ttlGPA=ttlGPA+marks[i];
        }
            clsavg=ttlGPA/number;
            cout<<"\nThe Average is: "<<clsavg<<endl;
    }

    else
    {

    }
}

已完成一半。当我构建并运行CodeBlocks时,立即出现错误: i.imgur.com

我尝试找到错误的来源,我认为它是由代码中的以下内容引起的:

int o,i,marks[i],ttlcredit=0;

让我这么想是因为当我从标记[i] 中删除 [i] 时,我将不会收到该错误。

我认为堆栈溢出是因为我使用Microsoft Visual Studio来帮助我调试,这是他们给我的错误:

Unhandled exception at 0x0041419e in Project (1).exe: 0xC00000FD: Stack overflow.

我的问题是......

  1. 这是问题的主要原因吗?
  2. 如何解决此问题?

4 个答案:

答案 0 :(得分:0)

您必须使用正长度初始化标记数组。

首先获取学生数,然后使用该数字创建数组。

此外,您需要声明变量number

答案 1 :(得分:0)

正如其他答案所说的那样,问题是int i未经初始化使用。但是,建议修复

// initialze i
int marks[i];

不是标准C ++,但只能通过编译器扩展来实现。在C ++中,内置数组的长度必须是编译时常量。更好的解决方案是使用std::vector

// initialize i (better make it std::size_t instead of int)
std::vector<int> marks (i);

这将以安全且标准的符合方式创建可变长度数组。

答案 2 :(得分:0)

首先要说的是,你根本就不应该使用数组。它们在C和C ++中太奇怪了,而且我们在现代C ++中有更好的选择。

无论如何,无论您使用数组还是vector,都存在一些重要问题。在讨论marks[i]之前,在此代码中查看credit[7][2]会更简单。

int o,i,marks[i],ttlcredit=0;
double ttlGPA=0,finalGPA=0,credit[7][2],clsavg;

这个维度在credit的声明中是明确的。这是七次二。很简单。您可以读取和写入credit[0][0]credit[6][1]以及许多其他值。但如果你超出范围,例如尝试使用credit[7][0],您的程序将编译并且可能出现一段时间,但它可能表现得非常糟糕并且未定义它的行为方式。它可能决定删除您计算机上的所有文件,它(严重)有权随意和疯狂地做任何事情。这是未定义的行为

无论如何,真正奇怪的是marks的声明。

int marks[i];

这肯定不会做你认为它做的事情。它没有创建一个可以用任意i&#34;索引的数组。不,它分配一个大小为i初始值的数组。但是i在这个阶段是不确定的,所以这没有意义。

i无论如何都与此无关。你想要这个数组有多大?答案是number,不是吗?这是您将在阵列中存储的人数。

因此,一个小的改进就是这样做,而不是int marks[i]

int marks[number];

但即使这样也不正确。数字的值不会设置到第cin >> number;行,因此您必须在行int marks[number]之后声明cin >> number; ,以确保marks 1}}具有正确的大小。

但是,但是,即使在这之后,我们仍然没有标准的C ++。可以int credit[7][2]执行,因为大小在编译时是固定的。通常不允许在运行时设置数组的大小,例如int marks[number]。如果你的编译器允许这个扩展(它来自C的称为可变长度数组),你可以使用它。

所以,这不是标准的C ++,它可能非常危险(参见未定义的行为)。解决方案是什么?

该解决方案是涉及阵列的任何问题的标准解决方案。停止使用数组。 (真的高级程序员,在特殊情况下,可能在现代C ++中使用std::array,甚至在旧版C ++中编写自己的std:: array克隆。但是原始C {{1}尽可能避免使用数组。)

[]

#include<vector> int o,i,ttlcredit=0; std::vector<int> marks; 最初为空。我们marks。相反,我们使用push_back将新项目附加到列表的末尾。

cin >> marks[i];

另外,请勿将int next_mark; cin >> next_mark; marks.push_back(next_mark); marks[i]一起使用。它可能看起来不错,但它很危险。最好使用vector来读取或写入元素。 marks.at(i)会为你做边界检查,如果at太小(小于0)或者对于矢量大小太大,会给你一个正确的错误信息。

答案 3 :(得分:-1)

int o,i,marks[i],ttlcredit=0;

我没有初始化。首先初始化我。 如果您不确定数组的大小,请动态分配它。

使用新的 请参阅此链接,了解如何使用新的 - cpluspluss