2015-01-31 3 views
0

Моя программа заключается в следующем:массив вызывает ошибку переполнения стека

#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. Как решить эту проблему?
+2

'i' неинициализирован, когда выделяется' marks [i] '. Кроме того, это расширение компилятора (не стандартное C++), вы должны установить 'i' в правильное значение, прежде чем выделять' int marks [i]; '. –

ответ

0

Вы должны инициализировать массив меток положительной длиной.

Сначала получите количество студентов, затем создайте массив, используя этот номер.

Кроме того, вам необходимо объявить переменную number.

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

i не инициализирован. сначала инициализируйте i. Если вы не уверены в размере массива, выделите его динамически.

использовать новый см эту ссылку о том, как использовать новый - cpluspluss

+0

Спасибо за совет! это сработало! – user4514279

+0

Возможно, это сработало, но это, вероятно, все еще неверно. Если сначала 'i = 0', то' marks [i] 'даст вам * пустой * массив. –

+0

Если это вам помогло. Можете ли вы принять ответ или перенести его? Спасибо :) – CodeShadow

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); 

Это создаст переменную массив длины в надежном и стандартным образом конформного.

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». Нет, он выделяет массив, размер которого является начальным значением i. Но i не определено на этом этапе, так что это бессмысленно.

Но i здесь не имеет отношения к делу. Насколько велик этот массив? Ответ number, не так ли? Это количество людей, которые вы будете хранить в своем массиве.

Итак, небольшое улучшение должно сделать это вместо int marks[i].

int marks[number]; 

Но это неправильное. Величина номера не устанавливается до линии cin >> number;, поэтому вы должны объявить int marks[number]после линии cin >> number;, чтобы обеспечить правильный размер marks.

Но, но, даже после всего этого, у нас до сих пор нет стандартного C++. Это нормально, чтобы сделать int credit[7][2], потому что размер фиксируется во время компиляции. Обычно вам не разрешается устанавливать размер массива во время выполнения, например. int marks[number]. Возможно, вы сможете использовать его, если ваш компилятор разрешает это расширение (он называется Variable Length Array, от C).

Итак, это не стандартный C++, и это потенциально очень опасно (см. Неопределенное поведение). Какое решение?

Решение является стандартным решением для любой задачи, связанной с массивами. Прекратите использование массивов. (Действительно продвинутые программисты, в определенных ситуациях, может использовать std::array в современном C++, или даже написать свой собственный клон std:: array в старых C++. Но сырые C [] массивы следует избегать, где это возможно.)

#include<vector> 
int o,i,ttlcredit=0; 
std::vector<int> marks; 

marks изначально пуст. Мы не do cin >> marks[i];. Вместо этого мы используем push_back для добавления новых элементов в конец списка.

int next_mark; 
cin >> next_mark; 
marks.push_back(next_mark); 

Кроме того, не используйте marks[i] с vector. Это может выглядеть нормально, но это опасно. Лучше использовать marks.at(i) для чтения или записи элемента.at проведет проверку границ, предоставив вам правильное сообщение об ошибке, если i слишком мало (меньше 0) или слишком велико для размера вектора.

Смежные вопросы