2013-05-18 1 views
0

// Короче говоря, пытаясь сделать медиа-библиотеку, но я на 100% полную потерю, почему я не могу заставить эти данные работать. Это мой main.cppЯ продолжаю получать ошибку переполнения стека и попытался исправить это в течение 3 дней. Я создаю медиа-библиотеку для компакт-дисков

#include "CDclass.h" 

bool fills = true;//Public Switch to turn on/off autofill of "Data" classes. 
bool runner = true;//Public switch that helps with the program functionality(DO NOT EDIT) 

void main() 
{ 
int decision; 
unsigned int total = 5; 
vector<string> titles; 
vector<double> time; 
string artist; 
string name; 

titles.resize(total); 
time.resize(total); 

vector<cdStorage> Data;//A vector of classes 

cdStorage newCD; 
Data.push_back(newCD); 
Data.push_back(newCD); 
Data.push_back(newCD);//This was used as a sizing test and it works. 
cdStorage::cdStorage(total); 

    //I used this to loop without restarting main. 

while(runner == true) 
{ 
    if(fills == true)//Autofill to get the program running 
    { 
     artist = "Bunny"; 
     name = "Bread"; 

     for(unsigned int x = 0; x < Data.size(); x++) 
     { 
      cdStorage::cdStorage(total); 
      Data[x].setNewArtist(artist); 
      Data[x].setNewName(name); 

      for(unsigned int y = 0; y < total; y++) 
      { 
       titles[y] = "TestfieldBanana!"; 
       time[y] = 12.13; 
       Data[x].setNewTitles(y, titles[y]); 
       Data[x].setNewTime(y, time[y]); 
      } 
     } 
     fills = false; 
    } 

    cout << Data[0].getNewArtist() << endl; 
    cout << "*******************" << endl << 
      "*Media Awesomsauce*" << endl << 
      "*******************" << "\n\n" << 
      "********************" << endl << 
      "* 1: Check Library *" << endl << 
      "* 2: Add CD  *" << endl << 
      "* 3: Delete CD  *" << endl << 
      "* 4: Exit Program *" << endl << 
      "********************" << "\n\n" << 
      "Decision:_"; 

    cin >> decision; 
//The majority of all of this is very self explanatory. 
    if(decision == 1) 
    { 
     for(unsigned int x = 0; x < Data.size(); x++) 
     { 
      cdStorage::cdStorage(total); 
       cout << Data[x].getNewName() << "\t"; 
       cout << Data[x].getNewArtist() << "\t"; 
      for(unsigned int y = 0; y < total; y++) 
      { 
       //int length = Data[x].getNewName().length(); 

       cout << "\t\t\t" << Data[x].getNewTitles(y); 
       cout << "\t" << Data[x].getNewTime(y) << endl; 
      } 
     } 

    }else if(decision == 2) 
    { 
     Data.push_back(newCD); 

     system("CLS"); 

     cout << "What is the name of the CD: "; 
     cin >> name; 
     cout << "\nWhat is the name of the Artist: "; 
     cin >> artist; 
     cout << "\nHow many songs are there: "; 
     cin >> total; 

     cdStorage::cdStorage(total); 
     titles.resize(total); 
     time.resize(total); 
     Data[Data.size()].setNewName(name); 
     Data[Data.size()].setNewArtist(artist); 

     cout << "What are the song titles and lengths:\n"; 

     for(unsigned int x = 0; x < total; x++) 
     { 
      cout << "Title " << x+1 << ": "; 
      getline (cin, titles[x]); 
      cout << "Length(Example: 3.36 for 3 mins and 36 seconds): "; 
      cin >> time[x]; 
      cout << endl; 

      Data[Data.size()].setNewTitles(x, titles[x]); 
      Data[Data.size()].setNewTime(x, time[x]); 
     } 

    }else if(decision == 3) 
    { 

    }else if(decision == 4) 
    { 
     runner = false; 

    }else 
    { 
     system("CLS"); 
     cout << "Error: You must choose a number between 1-5...\n\n"; 
     system("pause"); 
     system("CLS"); 
    } 
    } 
} 

// Это мой CDWorks.cpp

#include "CDclass.h" 

//Constructor 
cdStorage::cdStorage(){}; 
//Overloaded Constructor 
cdStorage::cdStorage(unsigned int theTotal) 
{ 
newTotal = theTotal; 
newTitles.resize(newTotal); 
newTime.resize(newTotal); 
} 
//Accessors 
unsigned int cdStorage::getNewTotal() const 
{ 
    return newTotal; 
} 

string cdStorage::getNewTitles(unsigned int x) const 
{ 
    return newTitles[x]; 
} 

double cdStorage::getNewTime(unsigned int x) const 
{ 
    return newTime[x]; 
} 

string cdStorage::getNewArtist() const 
{ 
    return newArtist; 
} 

string cdStorage::getNewName() const 
{ 
    return newName; 
} 

//Mutators 
void cdStorage::setNewTotal(unsigned int theTotal) 
{ 
    newTotal = theTotal; 
} 

void cdStorage::setNewTitles(unsigned int x, string theTitle) 
{ 
    newTitles[x] = theTitle; 
} 

void cdStorage::setNewTime(unsigned int x, double theTime) 
{ 
    newTime[x] = theTime; 
} 

void cdStorage::setNewArtist(string theArtist) 
{ 
    newArtist = theArtist; 
} 

void cdStorage::setNewName(string theName) 
{ 
    newName = theName; 
} 
//Destructor 
cdStorage::~cdStorage(){} 

// Это мой CDClass.h

#include <iostream> 
#include <string> 
#include <vector> 

using namespace std; 

#ifndef CDCLASS_H 
#define CDCLASS_H 

class cdStorage 
{ 
private: 
unsigned int newTotal; 
vector<string> newTitles; 
vector<double> newTime; 
string newArtist; 
string newName; 

public: 
//Constructor 
cdStorage(); 
//Overloaded Constructor 
cdStorage(unsigned int); 
//Destructor 
~cdStorage(); 
//Accessors 
unsigned int getNewTotal() const; 
string getNewTitles(unsigned int) const;//The integer is to track which element needs returned. 
double getNewTime(unsigned int) const; 
string getNewArtist() const; 
string getNewName() const; 
//Mutators 
void setNewTotal(unsigned int); 
void setNewTitles(unsigned int, string); 
void setNewTime(unsigned int, double); 
void setNewArtist(string); 
void setNewName(string); 
}; 

#endif 
+2

Где происходит переполнение стека? Также используйте 'int main' и никогда не ставьте' использование пространства имен xxx; 'в таких заголовках. – chris

+3

Пожалуйста, отредактируйте заголовок, чтобы указать на проблему, с которой вы сталкиваетесь, а не на то, как сильно вы настойчивы. Если вы запускаете программу под отладчиком, она ломается в строке, где возникает проблема, и если да, то в какой строке это? – Praetorian

+0

Вы должны действительно рассмотреть возможность использования базы данных, чем писать самостоятельно: http://stackoverflow.com/questions/2648802/at-what-point-is-it-worth-using-a-database/2649916#2649916 –

ответ

1
Data[Data.size()].setNewName(name); 

Этот доступ проходит мимо конца вектора, он имеет только Data.size() элементов, начиная с нуля. Это неопределенное поведение и, вероятно, проблема.

Возможно, это не проблема, но, поскольку вы не сказали, где происходит ошибка, это трудно понять. У вас есть неудачная программа, вы должны уметь ее отлаживать и говорить, где она взрывается ... у вас было три дня, чтобы научиться использовать отладчик!

Пока вы не знаете, что вы делаете, я предлагаю вам прекратить использование [x] векторам доступа и перейти к использованию функции at(x), которая делает то же самое, но проверяет, что x является допустимым индексом и не больше размера вектора. Если бы вы это сделали, у вас возникло бы исключение при первой проблеме, вместо неопределенного поведения и переполнения стека.

Есть целый ряд других вопросов ...

Положите включаемые охранник в верхней части файла, а не после того, как другие заголовков.

Никогда не ставьте using namespace на пространство пространства имен в заголовке.

Вы продолжаете делать это:

cdStorage::cdStorage(total);

Что это должен делать и почему вы продолжаете делать это?

Вы должны использовать инициализаторы членов в конструкторах вместо того, чтобы изменять их в теле конструктора:

cdStorage::cdStorage(unsigned int theTotal) 
{ 
newTotal = theTotal; 
newTitles.resize(newTotal); 
newTime.resize(newTotal); 
} 

т.е. сделать это вместо того, чтобы:

cdStorage::cdStorage(unsigned int theTotal) 
: newTotal(theTotal), newTitles(theTotal), newTime(theTotal) 
{ } 
2

Data[Data.size()] обращается за пределами вектора Data, который не определен поведение, поэтому все может случиться.

Кроме того, я не знаю, что вы думаете, многократно называя cdStorage::cdStorage(total);, но он ничего не делает, кроме создания нового (анонимного) объекта, который сразу же отбрасывается. вы создали

Всех cdStorage s были созданы с использованием по умолчанию (без параметров) конструктора, который оставляет newTotal полностью неинициализированным, и vector s является пустым.Вы не можете изменить их, вызвав впоследствии конструктор (я подозреваю, что это то, что вы пытаетесь выполнить).

Поскольку векторы пусты, когда вы говорите, например. newTitles[x] = theTitle;, вы получаете доступ к недопустимой памяти, а это значит, что ваша программа снова имеет неопределенное поведение.

Очень сложно сказать, являются ли они причиной ваших проблем, но вы должны, вероятно, исправить их прежде, чем продолжить.

Возможно, вам следует рассмотреть главу о конструкторах и создании экземпляра в вашей Fine Book.

+0

Ах да, я остановился, когда увидел «Data [Data.size()]» и не дошел до чтения «CDWorks.cpp», чтобы увидеть, что 'Data [x] .setNewTitles (y, title [y]) ; 'также является доступом за пределы границ –