Выражение: _BLOCK_TYPE_IS_VALID (pHead-> nBlockUse) Ошибка

Эта ошибка возникает во время выполнения, и я не уверен, что ее вызывает — код выглядит правильно для меня.

#include <iostream>
#include <string>

using namespace std;

struct Room {
int d_noSeat;
bool d_hasProjector;
Room() = default;
Room(const Room& r);
};

class Event {
Room* d_room;
std::string d_name;
public:
Event();
Event(const Event& e);
~Event();
void set(Room r, const std::string& name);
void print();
};

Event::Event() : d_room(0), d_name("") {};

void Event::print() {
std::cout << "Event: " << d_name;
if (d_room != 0) {
std::cout << " in size " << d_room->d_noSeat;
if (d_room->d_hasProjector)
std::cout << " with";
else
std::cout << " without";
std::cout << " projector";
}
std::cout << std::endl;
return;
}

void printEvent(Event e) {
e.print();
return;
}void Event::set(Room r, const std::string& name) {
d_room = &r;
d_name = name;
}

// Room shallow copy constructor
Room::Room(const Room& r) :
d_noSeat(r.d_noSeat),
d_hasProjector(r.d_hasProjector)
{ }

// Event deep copy constructor
Event::Event(const Event& e) :
d_name(e.d_name),
d_room(new Room(*e.d_room))
{ }

// Event destructor
Event::~Event()
{
delete[] d_room;
}int main() {
const int noLect = 5;
Room r;
Event lectures[noLect];

for (int i = 0; i < noLect; ++i) {
r.d_noSeat = i + 1;
r.d_hasProjector != r.d_hasProjector;
lectures[i].set(r, "CSI2372");
lectures[i].print();
}
std::cout << "-------------------" << std::endl;
for (int i = 0; i < noLect; ++i) {
printEvent(lectures[i]);
}
return 0;
}

Ошибка, по-видимому, возникает в строке 52 (первая строка в функции print ()). В дополнение к этому, напечатанный текст отображает очень большие и часто отрицательные числа. Чем это вызвано?

3

Решение

вопрос

void Event::set(Room r, const std::string& name)
{
d_room = &r;
//      ^
d_name = name;
}

Вы ссылаетесь на временный объект: Room r передается по значению, которое уничтожается в конце области: },

Вместо этого вы должны перераспределить указатель на член:

d_room = new Room(r);

Почему это пошло не так

Потому что вы пишете код в стиле C в классах C ++.

В C ++ мы склонны:

  1. Избегайте голых указателей, предпочитайте умные указатели:

    class Event
    {
    std::shared_ptr<Room> d_room;
    ...
    
    Event::~Event() { /* no need to delete */ }
    
  2. Использовать перегрузку конструктора (вместо использования set-подобные функции после постройки):

    Event(Room& r, const std::string& name):
    d_room(new Room(r)),
    d_name(name)
    {}
    
  3. Передать по ссылке:

    void set(Room& r, const std::string& name);
    
  4. Избегайте необработанных массивов, используйте вместо них средства STL:

    std::vector<Event> lectures;
    // or
    std::array<Event, 5> lectures;
    

Еще одна проблема

r.d_hasProjector != r.d_hasProjector; // checks if r.d_hasProject is not itself

Вы, вероятно, хотите

r.d_hasProjector = !r.d_hasProjector;

Полный код: ссылка на сайт

Кроме того, вот обязательная ссылка на продвинутый материал C ++, который, я считаю, будет очень полезен для вас: http://www.parashift.com/c++-faq/

Редактировать: Я забыл о вашем вопросе:

В дополнение к этому, напечатанный текст отображает очень большие и часто отрицательные числа. Чем это вызвано?

Эти цифры являются мусором. Переменные, которые не были явно инициализированы, не инициализируются вообще. Память выделена, но содержит старую информацию из предыдущей программы. Это может содержать что угодно. Когда вы читаете из неинициализированных переменных, вы получите этот мусор. У вас был указатель, который указывал на уничтоженный объект. Таким образом, указатель был фактически неинициализирован.

9

Другие решения

Ваша проблема здесь:

void Event::set(Room r, const std::string& name) {
d_room = &r;
d_name = name;
}

&r принимает адрес объекта, время жизни которого заканчивается при возврате функции, что приводит к неопределенному поведению при последующем обращении к нему.

Если вы хотите использовать указатели, вам нужно распределить их динамически:

void Event::set(Room* r, const std::string& name) {
d_room = r;
d_name = name;
}

// ...
for (int i = 0; i < noLect; ++i) {
Room* r = new Room;
r->d_noSeat = i + 1;
r->d_hasProjector != r.d_hasProjector;
lectures[i].set(r, "CSI2372");
lectures[i].print();
}
// ...

Но это не похоже, что вам нужны указатели здесь, вы должны иметь возможность

Room d_room;

в Event учебный класс.

1

По вопросам рекламы [email protected]