C ++函数导致应用程序崩溃,不能正常工作 [英] C++ Function causing app to crash and not working properly

查看:113
本文介绍了C ++函数导致应用程序崩溃,不能正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程式发生问题,我的PrintAll功能无法正常运作,最终导致应用程式崩溃。我的应用程序应该从文件中读取字符串并将其插入数组。问题是它读取不正确,最终会崩溃我的应用程序。这里是我认为问题所在:

A problem has come up in my application where my PrintAll function will not work correctly and only ultimately crash my application. My app is supposed to read strings from a file and insert them into an array. The problem is it is reading incorrectly and will ultimately crash my app. Here is where I think the problem lies:

int main()
{
    LoadMovies();

    MovieList *movies = LoadMovies();
    //movies->MovieList::PrintAll();

    //    // test methods for the Movie and 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;

    for (int i = 0; i < 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();
}

完成示例:

/*
 * File: MovieStatsProgram.cpp
 * Author:
 * Date:
 * ===============================================================
 * This is a console app to test the Movie and MovieList classes.
 *
 * TODO:
 *
 * You need to finish the implementation of the loadMovies method
 * to create and initialize the MovieList object.
 *
 * You also need to create three static methods:
 *
 * PrintAllMoviesMadeInYear - it will print all the movies made in a
 * given year once sort in alphabetical order and once sorted by the number
 * of votes with the movie with the most number of votes printed first.
 *
 * PrintAllMoviesWithStartLetter - it will print all the movies started with
 * a given letter sorted in alphabetical order
 *
 * PrintAllTopNMovies - it will display the top N movies based on the 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 is full" << endl;
        return;
    }

    ++last_movie_index;
    movies[last_movie_index] = m;
}

string MovieList::PrintAll() {
    for (int i = 0; i < 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 for the Movie and 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;

    for (int i = 0; i < 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();
}

当我在主函数中使用MovieList :: PrintAll时, ,当我把它放在LoadMovies函数,它会在崩溃之前读取和添加数据不正确。列表大小为251,应用程序只读取相同的数据251次。

When I use MovieList::PrintAll in the main function, my function just crashes, and when I put it in the LoadMovies function, it will read and add data incorrectly before crashing. The size of the list is 251 and the application will just read the same data 251 times.

推荐答案

1:正如Brad S所说,你的函数什么也不返回。这是一个没有。

1: As Brad S stated, your function returns nothing. This is a no-no.

MovieList* LoadMovies()
{
    MovieList ml = MovieList(movies.size());
    // Your function returns a pointer to a MovieList, so...
    return &ml;
}

所以,问题2是你要返回一个指针你在你的函数中在堆栈上创建的东西。当你试图在你的函数之外访问它时,你会遇到未定义的行为。

So, problem #2 is that you're going to return a pointer to something you created on the stack in your function. When you try to access it outside of your function, you'll run into undefined behavior.

选项1:

 MovieList* ml = new MovieList( movies.size() );
 return ml;

当你完成后,现在需要删除ml。

You now need to delete ml when you're done w/ it.

选项2:
更改你的函数返回一个非指针...那么你没有管理内存的麻烦。

Option 2: Change your function to return a non-pointer... then you don't have the hassle of managing the memory.

编辑:尝试此

int main()
{
    // Don't need this
    // LoadMovies();

    MovieList *movies = LoadMovies();

    // Uncommented this
    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;

    for (int i = 0; i < 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;
}

这篇关于C ++函数导致应用程序崩溃,不能正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆