C++ 表达式:_BLOCK_TYPE_有效(pHead->;nBlockUse)错误

C++ 表达式:_BLOCK_TYPE_有效(pHead->;nBlockUse)错误,c++,class,runtime-error,deep-copy,shallow-copy,C++,Class,Runtime Error,Deep Copy,Shallow Copy,这个错误发生在运行时,我不确定是什么导致了它-代码在我看来是正确的 #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;

这个错误发生在运行时,我不确定是什么导致了它-代码在我看来是正确的

#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;
}
#包括
#包括
使用名称空间std;
结构室{
int d_noSeat;
布尔杜哈斯投影仪;
Room()=默认值;
房间(施工室和r);
};
班级活动{
房间*d_房间;
std::字符串d_名称;
公众:
事件();
事件(持续事件&e);
~Event();
无效集(房间r,常数标准::字符串和名称);
作废打印();
};
事件::事件():d_房间(0),d_名称(“”{};
void事件::print(){
std::cout您的问题在这里:

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 r
通过值传递,该对象在作用域的末尾被销毁:
}

相反,您必须重新分配成员指针:

d_room = new Room(r);
为什么会出错 因为您在C++类中编写C样式代码。 在C++中,我们倾向于:

  • 避免裸指针,更喜欢智能指针:

    class Event 
    {
        std::shared_ptr<Room> d_room;
     ...
    
    Event::~Event() { /* no need to delete */ }
    
  • 通过参考:

    void set(Room& r, const std::string& name);
    
  • 避免使用原始阵列,而是使用STL工具:

    std::vector<Event> lectures;
    // or
    std::array<Event, 5> lectures;
    
    std::向量讲座;
    //或
    阵列讲座;
    
  • 另一个问题
    r.d\u投影仪!=r、 d_hasProjector;//检查r.d_hasProject是否不是其自身

    你可能想要

    r.d\u hassprojector=!r、 杜哈斯投影仪

    完整代码:

    还有,这里是一个关于高级C++的必读链接,我相信,它会对你很有用:

    编辑:我忘了你的问题:

    除此之外,打印文本显示的数字非常大,通常为负数。这是什么原因造成的


    那些数字都是垃圾。未显式初始化的变量根本不会初始化。内存已分配,但保存以前程序中的旧信息。它可以包含任何东西。当您读取未初始化的变量时,您将得到这些垃圾。你有一个指针指向一个被破坏的物体。所以指针实际上是未初始化的。

    那么现在发生的是,传递给d_room的地址在Event::set(…)函数的末尾被销毁了?有没有一种方法可以实现这个函数,保持指针的使用,但不改变主方法?这是给定的,其余的代码都基于它。不过谢谢你的帮助,你已经把事情弄清楚了。不需要通过指针传递,引用就足够了。无需分配
    房间*r=新房间在类外。没有人知道谁和什么时候删除它。最后它会泄漏。@Drop使用参数引用和使用指针一样糟糕。你分配房间的位置取决于谁拥有它。@ USER9390906如果你给了代码<主代码> /代码>,并且你需要使用指针,那么它是错误的,你应该告诉任何给你的人去上C++的基础课程。这很完美,非常感谢。回答了我所有的问题,并给出了一些很好的提示。你为什么要使用
    Room&r
    而不是
    const Room&r
    ,这是一种纯粹的输入,不是吗?我们不希望也不希望它在函数内部发生更改,与实际作为常量引用提供的名称字符串相同。@DaedalusAlpha您是对的,它必须是
    const
    ref。不知何故,我忽略了这一点。但是,我认为最好在这里按值传递字符串,这样C++11移动语义就可以工作了。这是否回答了您的问题?
    Event(Room& r, const std::string& name):
            d_room(new Room(r)),
            d_name(name)
    {}
    
    void set(Room& r, const std::string& name);
    
    std::vector<Event> lectures;
    // or
    std::array<Event, 5> lectures;