Реализация пула объектов C ++ с ошибкой SIGILL - PullRequest
0 голосов
/ 23 апреля 2020

Я пытаюсь немного узнать о памяти в C ++, и поэтому я работаю над простой реализацией Object Pool. Вот что у меня есть:

template<typename T, std::size_t Size>
class MemoryPool {
public:
    MemoryPool() = default;

    template<typename... Args>
    T* create(Args&&... args) {
        auto idx = 0;
        while (isOccupied[idx]) ++idx;

        if (idx >= Size) throw std::out_of_range("No memory left");
        isOccupied[idx] = true;

        auto t = data[idx];

        auto datum = T(std::forward<Args>(args)...);
        data[idx] = datum; // error here
    }

    void destroy(T* element) {
        auto idx = 0;
        while (&data[idx] != element) idx++;
        isOccupied[idx] = false;

        operator delete(element);
    }

private:
    T* data = reinterpret_cast<T*>(std::malloc(sizeof(T) * Size));
    std::array<bool, Size> isOccupied{};
};

Однако, когда я отлаживаю реализацию, я получаю ошибку SIGILL при попытке присвоить data[idx]. Я не уверен, почему это так, поскольку я вполне уверен, что правильно инициализировал data и datum.

Минимальный воспроизводимый пример:

struct A {
    int i;
    explicit A(int i) : i(i) {}
};

int main() {
    MemoryPool<A, 3> pool{};
    auto a = pool.create(1);
    return 0;
}

Я использую C ++ 20 и Clang 10 с CLion IDE.

1 Ответ

1 голос
/ 23 апреля 2020

Одна ошибка состоит в том, что ваша create функция не может вернуть значение, когда она должна вернуть T*. Таким образом, вызывается неопределенное поведение.

template<typename... Args>
T* create(Args&&... args)
{
  //...
}  // gets to here without returning a value

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...