2014-12-04 2 views
-1

У меня есть класс, содержащий массив указателей объектов в качестве его переменной-члена. В настоящее время у меня возникает проблема с тем, что компилятор копирует объект в конец массива, как когда я просматриваю программу, массив объектов читает, что его память не может быть прочитана. Кто-нибудь знает, в чем проблема?C++: компилятор не может прочитать массив объектов

void Notifications::operator+=(const iMessage& src) { 
    iMessage** temp2 = nullptr; 
    temp2 = new iMessage*[size+1]; 
    if (size != 0){ 
     for (int i = 0; i < size; i++) { 
      *temp2[i] = *messages[i]; 
     } 
    } 
    *temp2[size] = src; //compiler states that it cannot read the data from temp2 after this point 
    delete[]messages; 
    for (int i = 0; i < size + 1; i++) { 
     *messages[i] = *temp2[i]; //Unhandled exception at 0x00C58F99 in w5.exe: 0xC0000005: Access violation reading location 0x00000000. 
    } 
    size++; 
} 

Notifications.h

#include "iMessage.h" 
#include <vector> 

namespace w5 { 
    class Notifications { 
     int size; 
     iMessage **messages; 
    public: 
     Notifications(); 
     Notifications(const Notifications&); 
     Notifications& operator=(const Notifications&); 
     Notifications(Notifications&&); 
     Notifications&& operator=(Notifications&&); 
     ~Notifications(); 
     void operator+=(const iMessage&); 
     void display(std::ostream&) const; 
    }; 
} 

IMessage.h

#ifndef _I_MESSAGE_H_ 
#define _I_MESSAGE_H_ 

// Workshop 5 - Containers 
// iMessage.h 

#include <iostream> 
#include <fstream> 

namespace w5 { 
    class iMessage { 
    public: 
     virtual void display(std::ostream&) const = 0; 
     virtual iMessage* clone() const = 0; 
     virtual bool empty() const = 0; 
    }; 

    iMessage* getMessage(std::ifstream&, char); 
} 
#endif 

Message.h

#include "iMessage.h" 
namespace w5{ 
    class Twitter : public iMessage { 
     std::string msg; 
    public: 
     Twitter(char, std::ifstream&); 
     virtual void display(std::ostream&) const; 
     virtual iMessage* clone() const; 
     virtual bool empty() const; 
    }; 

    class Email : public iMessage { 
     std::string msg; 
    public: 
     Email(char, std::ifstream&); 
     virtual void display(std::ostream&) const; 
     virtual iMessage* clone() const; 
     virtual bool empty() const; 
    }; 
} 
+2

Просто используйте 'вектор >'. И ваш 'iMessage' должен иметь виртуальный деструктор. Кроме того, компилятор говорит, что он не может прочитать массив, а затем сработает? Как и в, он создает внутреннюю ошибку компилятора? Я считаю, что трудно поверить. Какой компилятор, версия и какое сообщение об ошибке вы получаете? –

+0

Я могу порекомендовать реорганизовать функцию. Не могу принять «образ мышления», извините. – i486

+0

Вы косвенны через 'temp2 [i]' перед тем, как выделить место для него. – Barmar

ответ

0

Сначала вы

delete[]messages; 

тогда вы

*messages[i] = *temp2[i]; 

пытается получить доступ к массиву вы только что удалили. Я думаю, вы просто хотите взять указатель на вы только что создали массив:

messages = temp2; 

Вы также сделать

*temp2[size] = src; 

когда temp2[size] не указывает ни на что. Вероятно, это должно быть

temp2[size] = src.clone(); 

Чтобы сделать постоянную копию аргумента и сохранить его в массиве.

Весьма сложно следовать этому странному указателю-жонглированию; Я думаю, вы также хотите удалить каждый элемент messages до messages, чтобы избежать утечек. Почему бы просто не использовать std::vector, чтобы позаботиться о распределении памяти для вас? Это позволит сократить весь безумный танец

std::vector<std::unique_ptr<iMessage>> messages; 

void operator+=(const iMessage & src) { 
    messages.emplace_back(src.clone()); 
} 

Кроме того, _I_MESSAGE_H_ является reserved name. Вы должны удалить главный символ подчеркивания.

0

1) Просто используйте vector.

2) Вы всегда должны отправлять сообщения о компиляторе. «компилятор заявляет, что он не может прочитать данные из temp2 после этого момента» недостаточно.

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

4) Вы удаляете массив messages, а затем продолжаете копировать обратно в него, как если бы он все еще был там. (То, что вы на самом деле хотите сделать, это просто назначить messages = temp2.)

5) Вы нарезаете предметы повсюду, используя назначение, чтобы попытаться скопировать объекты iMessage. Есть причина, почему iMessage имеет функцию clone().

+0

Gotcha. Я добавил точное сообщение компилятора в отредактированном оригинальном сообщении. Спасибо за советы, я попытаюсь посмотреть, смогу ли я это выяснить. – karsius

+0

Это не сообщение компилятора. Это ваша ошибка. –

0

Вы хотите преобразовать ссылку на const в указатель, не являющийся константой. Интересно, что компилятор не бросает ошибок. Какой компилятор вы используете?

Что-то вроде этого невозможно?

void Notifications::operator+=(iMessage* src) { 

Я не проверял, но это должно работать:

void Notifications::operator+=(iMessage& src) { 
    *bar[foo] = &src; 
Смежные вопросы