简体   繁体   English

为什么不能将新对象添加到对象指针数组中?

[英]Why can't I add new object to my array of object pointers?

I have a MovieController object with an array of Movie objects. 我有一个带有Movie对象数组的MovieController对象。 I have a MovieView object that calls 'doAddMovie' on the controller. 我有一个MovieView对象,该对象在控制器上调用“ doAddMovie”。

When I call 'doAddMovie' in the MovieController's constructor, a movie gets added to the array. 当我在MovieController的构造函数中调用“ doAddMovie”时,会将电影添加到数组中。 But when I call 'doAddMovie' from the MovieView there's a segmentation fault. 但是,当我从MovieView调用“ doAddMovie”时,出现了分割错误。

Can anyone tell me what I'm doing wrong? 谁能告诉我我在做什么错?

MovieController.h MovieController.h

#ifndef MOVIECONTROLLER_H
#define MOVIECONTROLLER_H

#include "MovieView.h"
#include "Movie.h"

class MovieView;

class MovieController
{
  public:
    MovieController();
    void doAddMovie(string title, int year, string genre);

  private:
    MovieView* movieView;
    Movie** movies;
};

MovieController.cc: MovieController.cc:

const int MAX_MOVIES = 10;

MovieController::MovieController() {
  movies = new Movie*[MAX_MOVIES];
  doAddMovie("Star Wars", 1977, "SciFi"); // <<-- this works
}

/* when I call this method from my MovieView object, I get a segmentation fault, pretty
 * sure the fault happened on line:  movies[i] = new Movie(title, year, genre);
 */
void MovieController::doAddMovie(string title, int year, string genre) {
  cout << "doAddMovie; title=" << title << "; year=" << year << "; genre =" << genre;
  int i = 0;
  while (i < MAX_MOVIES) {
    if (movies[i] == NULL) {
      movies[i] = new Movie(title, year, genre); <<-- segmentation fault here
      break;
    }
    i = i+1;
  }
  return;
}

doAddMovie() expects to find a NULL pointer on an available slot, but you are not initializing the array slots to NULL after you have allocated the array, so the contents of the array will be random garbage. doAddMovie()期望在可用插槽上找到NULL指针,但是在分配数组之后,您不会将数组插槽初始化为NULL,因此数组的内容将是随机垃圾。 The fact that doAddMovies() works when called in the constructor is a fluke. doAddMovies()在构造函数中调用时起作用的事实是偶然的。

Try this instead: 尝试以下方法:

class MovieController
{
public:
    MovieController();
    ~MovieController();

    void doAddMovie(string title, int year, string genre);

private:
    MovieView* movieView;
    Movie** movies;
};

MovieController.cc:
const int MAX_MOVIES = 10;

MovieController::MovieController()
{
    movies = new Movie*[MAX_MOVIES];
    memset(movies, 0, sizeof(Movie*)*MAX_MOVIES); // <-- add this
    doAddMovie("Star Wars", 1977, "SciFi");
}

MovieController::~MovieController()
{
    for (int i = 0; i < MAX_MOVIES; ++i)
        delete movies[i];
    delete[] movies;
}

void MovieController::doAddMovie(string title, int year, string genre)
{
    for (int i = 0; i < MAX_MOVIES; ++i)
    {
        if (movies[i] == NULL)
        {
            movies[i] = new Movie(title, year, genre);
            cout << "Movie added: title=" << title << "; year=" << year << "; genre =" << genre;
            return;
        }
    }

    cout << "Movie ignored: title=" << title << "; year=" << year << "; genre =" << genre;
}

With that said, you should embrace C++ memory management and not use a raw array at all: 话虽如此,您应该接受C ++内存管理,而根本不使用原始数组:

#include <vector>

class MovieController
{
public:
    MovieController();
    void doAddMovie(string title, int year, string genre);

private:
    MovieView* movieView;
    std::vector<Movie> movies;
};

MovieController.cc:

MovieController::MovieController()
{
    doAddMovie("Star Wars", 1977, "SciFi");
}

void MovieController::doAddMovie(string title, int year, string genre)
{
    movies.push_back(Movie(title, year, genre));
    cout << "Movie added: title=" << title << "; year=" << year << "; genre =" << genre;
}

Finally, if you are still getting the SEGFAULT after that, then make sure your MovieView object is calling doAddMovie() using a valid MovieController object pointer to begin with. 最后,如果在那之后仍然得到SEGFAULT,则确保您的MovieView对象使用有效的MovieController对象指针开始调用doAddMovie()

After taking a step back, I realized that I wasn't setting 'this' MovieController in the associated MovieView, so when MovieView was calling doAddMovie it was doing so on a different instance of MovieController that has an uninitialized array. 退后一步,我意识到我没有在关联的MovieView中设置“ this” MovieController,因此当MovieView调用doAddMovie时,它是在具有未初始化数组的MovieController的另一个实例上进行的。

Feeling stupid. 愚蠢的感觉。 But thanks anyway! 但是还是要谢谢!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM