передача shared_ptr этому объекту, владеющему ссылкой - PullRequest
0 голосов
/ 14 марта 2020

Класс SharedEditor владеет ссылкой на объект класса NetworkServer, тогда как объектам NetworkServer принадлежит std::vector<std::shared_ptr<SharedEditor>> из editors. В конструкторе SharedEditor вызывается метод server.connect() для сохранения его ссылки, в server.connect() вместо общего указателя на этот редактор сохраняется в server. Программа компилируется и выполняется, но она плохо завершается.

NetworkServer.h

#include <queue>
#include <memory>
#include "SharedEditor.h"
#include "Message.h"

class NetworkServer {
private:
    std::vector<std::shared_ptr<SharedEditor>> editors;
    std::deque<Message> messages;

public:
    int connect(std::shared_ptr<SharedEditor> sharedEditor);
};

NetworkServer.cpp

#include <algorithm>
#include "NetworkServer.h"

static int id = 0;

int NetworkServer::connect(std::shared_ptr<SharedEditor> sharedEditor) {
    editors.push_back(sharedEditor);
    return id++;
}

SharedEditor.h

#include <vector>
#include <map>
#include "Symbol.h"

class NetworkServer;

class SharedEditor {
private:
    NetworkServer& _server;

public:

    SharedEditor(NetworkServer &server);

};

SharedEditor.cpp

#include <exception>
#include <algorithm>
#include <random>
#include <iostream>
#include "SharedEditor.h"
#include "NetworkServer.h"

SharedEditor::SharedEditor(NetworkServer &server)
        : _server(server), _counter(0), base(32), boundary(10) {
    _siteId = server.connect(std::shared_ptr<SharedEditor>(this));
}

main.cpp

#include <iostream>
#include "NetworkServer.h"

int main() {
    NetworkServer network;
    SharedEditor ed1(network);
    SharedEditor ed2(network);


    return 0;
}

Возвращается с -1073740940 (0xC0000374)

1 Ответ

0 голосов
/ 14 марта 2020

Вы неправильно поняли, как работают умные указатели.

server.connect(std::shared_ptr<SharedEditor>(this))

Вы передаете указатель this объекту, расположенному в стеке. Вы должны передавать только указатели динамически размещенным объектам в куче памяти.

Вы должны сделать что-то вроде ниже, но ваши классы плохо спроектированы, так как из семантики не ясно, network будет владеть вновь выделенным объектом.

SharedEditor* ed1 = new SharedEditor(network);
...