Ошибка конструктора копирования C ++ / оператора присваивания - PullRequest
1 голос
/ 09 февраля 2012

У меня есть эти переменные:

char** wordList_;
int wordListCapacity_;
int* wordCountList_;
char* fileName_;
int nUniqueWords_;
int nTotalWords_;
int nTotalCharacters_;

Мой конструктор копирования:

FileIndex::FileIndex(const FileIndex& fi)
{
    fileName_ = new char[strlen(fi.fileName_) + 1];
    strcpy(fileName_, fi.fileName_);
    cout << "Jiasd?" << endl;
    wordListCapacity_ = fi.wordListCapacity_;
    nUniqueWords_ = fi.nUniqueWords_;
    nTotalWords_ = fi.nTotalWords_;
    nTotalCharacters_ = fi.nTotalCharacters_;

    wordList_ = new char*[wordListCapacity_];
    wordCountList_ = new int[wordListCapacity_];
    for(int i = 0; i < nUniqueWords_; i++) {
        wordList_[i] = fi.wordList_[i];
        wordCountList_[i] = fi.wordCountList_[i];
    }
}

Мой перегруженный оператор присваивания:

FileIndex& FileIndex::operator=(const FileIndex& fi)
{
    fileName_ = new char[strlen(fi.fileName_) + 1];
    strcpy(fileName_, fi.fileName_);
    wordListCapacity_ = fi.wordListCapacity_;
    nUniqueWords_ = fi.nUniqueWords_;
    nTotalWords_ = fi.nUniqueWords_;
    nTotalCharacters_ = fi.nTotalCharacters_;
    wordList_ = new char*[wordListCapacity_];
    wordCountList_ = new int[wordListCapacity_];
    for (int i = 0; i < nUniqueWords_; i++) {
        wordList_[i] = new char[strlen(fi.wordList_[i])+1];
        strcpy(wordList_[i], fi.wordList_[i]);
        wordCountList_[i] = fi.wordCountList_[i];
    }
    return *this;
}

Всякий раз, когда я создаю FileIndex (называемый FirstIndex) и инициализирую переменные-члены чем-то значимым (не NULL), у меня есть эти строки для проверки конструктора копирования и оператора присваивания:

FileIndex secondIndex = firstIndex;
FileIndex thirdIndex;
secondIndex = thirdIndex; // Segmentation fault here

Я получаю ошибку сегментации с оператором присваивания, но у меня есть ощущение, что это может быть из-за неисправного кода в конструкторе копирования. При этом, если есть ошибка в конструкторе копирования, то, вероятно, есть и ошибка в операторе присваивания.

Заранее спасибо за помощь!

Ответы [ 3 ]

2 голосов
/ 09 февраля 2012

Я думаю, что вы хотите использовать std::string и std::vector<T> для вашего класса.Кроме того, для того, что пойдет не так, нужно будет увидеть конструктор по умолчанию и деструктор.На первый взгляд, кажется, что вы, возможно, не инициализировали некоторые элементы в конструкторе по умолчанию.Кроме того, у вашего оператора присваивания есть несколько утечек ресурсов, и он будет очень плох, если вы попробуете самоназначение.В общем, я бы рекомендовал реализовывать операторы присваивания следующим образом:

T& T::operator= (T other) {
    other.swap(*this);
    return *this;
}

Это использует работу, проделанную для конструктора копирования, и использует элемент swap(), который обычно очень легко сделать.

1 голос
/ 09 февраля 2012

Проверьте свой конструктор копирования.

for(int i = 0; i < nUniqueWords_; i++) {
    wordList_[i] = fi.wordList_[i];
    wordCountList_[i] = fi.wordCountList_[i];
}

Проблема с wordList_[i] = fi.wordList_[i];.Вы не выделяете новую память и не выполняете здесь strcpy, как в операторе присваивания.Вместо этого ваша новая копия фактически указывает на данные из экземпляра, с которого она копирует.Я полагаю, что это может быть то, на что намекал Дэвид Шварц.

0 голосов
/ 09 февраля 2012

Похоже, что вы не можете правильно инициализировать wordListCapacity_ (трудно сказать, так как вы не показываете ctor по умолчанию). Так как это int, оно может иметь отрицательное значение, которое может вызвать ошибку segfault при попытке wordList_ = new char*[wordListCapacity_];. Могут быть и другие проблемы.

...