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

时间:2014-01-31 03:17:03

标签: c++ arrays pointers

我有一个MovieController对象,其中包含一个Movie对象数组。我有一个MovieView对象,在控制器上调用'doAddMovie'。

当我在MovieController的构造函数中调用'doAddMovie'时,会将一个影片添加到该数组中。但是,当我从MovieView调用'doAddMovie'时,会出现分段错误。

谁能告诉我我做错了什么?

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:

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

2 个答案:

答案 0 :(得分:3)

doAddMovie()期望在可用插槽上找到NULL指针,但是在分配了数组后你没有将数组插槽初始化为NULL,因此数组的内容将是随机垃圾。 doAddMovies()在构造函数中调用时有效的事实是侥幸。

请改为尝试:

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

话虽如此,你应该接受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;
}

最后,如果您在此之后仍然获得SEGFAULT,请确保您的MovieView对象使用有效的doAddMovie()对象指针来调用MovieController

答案 1 :(得分:1)

退后一步,我意识到我没有在关联的MovieView中设置'this'MovieController,所以当MovieView调用doAddMovie时,它是在具有未初始化数组的不同MovieController实例上这样做的。

感觉很蠢。但无论如何,谢谢!