C++ Function causing app to crash and not working properly -
a problem has come in application printall function not work correctly , crash application. app supposed read strings file , insert them array. problem is reading incorrectly , crash app. here think problem lies:
int main() { loadmovies(); movielist *movies = loadmovies(); //movies->movielist::printall(); // // test methods movie , movielist classes //printallmoviesmadeinyear(movies, 1984); //printallmovieswithstartletter(movies, 'b'); //printalltopnmovies(movies, 5); //delete movies; return 0; } movielist* loadmovies() { vector<string> movies; readmoviefile(movies); movielist ml = movielist(movies.size()); string name; int year; double rating; int votes; (int = 0; < movies.size(); i++) { istringstream input_string(movies[i]); getline(input_string, name, '\t'); input_string >> year >> rating >> votes; movie movie (name, year, votes, rating); ml.add(movie); } ml.printall(); }
complete example:
/* * file: moviestatsprogram.cpp * author: * date: * =============================================================== * console app test movie , movielist classes. * * todo: * * need finish implementation of loadmovies method * create , initialize movielist object. * * need create 3 static methods: * * printallmoviesmadeinyear - print movies made in * given year once sort in alphabetical order , once sorted number * of votes movie number of votes printed first. * * printallmovieswithstartletter - print movies started * given letter sorted in alphabetical order * * printalltopnmovies - display top n movies based on number of * votes */ #include <iostream> #include <sstream> #include <vector> #include <string> #include <iomanip> #include <fstream> using namespace std; class movie { public: movie(); movie(string n, int y, int v, double r); string get_name(); void set_name(string n); int get_year(); void set_year(int y); int get_votes(); void set_votes(int v); double get_rating(); void set_rating(double r); string printmovie(); private: string name; int year_made; int votes; double rating; }; movie::movie() { name = "null"; year_made = 0; votes = 0; rating = 0.0; } movie::movie(string n, int y, int v, double r) { name = n; year_made = y; votes = v; rating = r; } string movie::get_name() { return name; } void movie::set_name(string n) { name = n; } int movie::get_year() { return year_made; } void movie::set_year(int y) { year_made = y; } int movie::get_votes() { return votes; } void movie::set_votes(int v) { votes = v; } double movie::get_rating() { return rating; } void movie::set_rating(double r) { rating = r; } string movie::printmovie() { cout << fixed << setprecision(1) << rating << "\t\t" << votes << "\t\t" << "(" << year_made << ")" << "\t" << name << endl; } class movielist { public: movielist(int size); ~movielist(); int length(); bool isfull(); void add(movie const& m); string printall(); private: movie* movies; int last_movie_index; int movies_size; int movie_count = 0; }; movielist::movielist(int size) { movies_size = size; movies = new movie[movies_size]; last_movie_index = -1; } movielist::~movielist() { delete [] movies; } int movielist::length() { return last_movie_index; } bool movielist::isfull() { return last_movie_index == movies_size; } void movielist::add(movie const& m) { if (isfull()) { cout << "cannot add movie, list full" << endl; return; } ++last_movie_index; movies[last_movie_index] = m; } string movielist::printall() { (int = 0; < last_movie_index; i++) { movies[last_movie_index].movie::printmovie(); //cout << movies[last_movie_index] << endl; } } void readmoviefile(vector<string> &movies); movielist* loadmovies(); enum moviesortorder { by_year = 0, by_name = 1, by_votes = 2 }; int main() { loadmovies(); movielist *movies = loadmovies(); //movies->movielist::printall(); // // test methods movie , movielist classes //printallmoviesmadeinyear(movies, 1984); //printallmovieswithstartletter(movies, 'b'); //printalltopnmovies(movies, 5); //delete movies; return 0; } movielist* loadmovies() { vector<string> movies; readmoviefile(movies); movielist ml = movielist(movies.size()); string name; int year; double rating; int votes; (int = 0; < movies.size(); i++) { istringstream input_string(movies[i]); getline(input_string, name, '\t'); input_string >> year >> rating >> votes; movie movie (name, year, votes, rating); ml.add(movie); } ml.printall(); } void readmoviefile(vector<string> &movies) { ifstream instream; instream.open("imdbtop250.txt"); if (instream.fail()) { cout << "error opening imdbtop250.txt" << endl; exit(1); } while (!instream.eof()) { string movie; getline(instream, movie); movies.push_back(movie); } instream.close(); }
when use movielist::printall in main function, function crashes, , when put in loadmovies function, read , add data incorrectly before crashing. size of list 251 , application read same data 251 times.
you have 2 part problem:
1: brad s stated, function returns nothing. no-no.
movielist* loadmovies() { movielist ml = movielist(movies.size()); // function returns pointer movielist, so... return &ml; }
so, problem #2 you're going return pointer created on stack in function. when try access outside of function, you'll run undefined behavior.
option 1:
movielist* ml = new movielist( movies.size() ); return ml;
you need delete ml when you're done w/ it.
option 2: change function return non-pointer... don't have hassle of managing memory.
edit: try this
int main() { // don't need // loadmovies(); movielist *movies = loadmovies(); // uncommented delete movies; return 0; } movielist* loadmovies() { vector<string> movies; readmoviefile(movies); // change movielist* ml = new movielist(movies.size()); // change string name; int year; double rating; int votes; (int = 0; < movies.size(); i++) { istringstream input_string(movies[i]); getline(input_string, name, '\t'); input_string >> year >> rating >> votes; movie movie (name, year, votes, rating); ml.add(movie); } ml.printall(); // change return ml; }
Comments
Post a Comment