C++ Вопрос Ошибка: Нет подходящего конструктора по умолчанию

Пользователь
Статус
Оффлайн
Регистрация
5 Июл 2022
Сообщения
1,001
Реакции[?]
86
Поинты[?]
23K
Всем привет, дорогие форумчане. Решил сделать проект без crt. Отключил его, но столкнулся с той проблемой, что мне нужно использовать вектор, а я отключил crt. Пришлось писать свой класс vector. Столкнулся с следующей ошибкой при использовании метода push. Подумал проблема может быть в new, так как он использует malloc. Пришлось сделать свой malloc, переопределить оператор new, но все равно вылазит ошибка.
vector:
// Размер кучи
#define HEAP_SIZE 1024

// Память для кучи
static unsigned char heap[HEAP_SIZE];

// Текущий индекс свободной памяти
static size_t free_index = 0;

// Структура для записи о блоке памяти
typedef struct {
    size_t size;
    bool is_free;
} Block;

// Функция выделения памяти
void* my_malloc(size_t size) {
    // Поиск свободного блока памяти
    size_t index = 0;
    while (index < HEAP_SIZE) {
        Block* block = (Block*)&heap[index];
        if (block->is_free && block->size >= size) {
            // Найден подходящий блок
            block->is_free = false;
            return (void*)&heap[index + sizeof(Block)];
        }
        index += sizeof(Block) + block->size;
    }
    // Не удалось найти подходящий блок
    return NULL;
}

// Переопределение оператора new
void* operator new(size_t size) {
    return my_malloc(size);
}

// Функция освобождения памяти
void my_free(void* ptr) {
    unsigned char* mem = (unsigned char*)ptr;
    // Определяем индекс блока памяти
    size_t index = mem - heap;
    // Помечаем блок памяти как свободный
    Block* block = (Block*)&heap[index - sizeof(Block)];
    block->is_free = true;
}

// Переопределение оператора delete
void operator delete(void* ptr) noexcept {
    my_free(ptr);
}

template <typename T>
class Vector {
private:
    T* array; // указатель на динамический массив
    size_t capacity; // текущая емкость массива
    size_t size; // текущий размер массива

public:
    // Конструкторы
    Vector() : array(nullptr), capacity(0), size(0) {}

    explicit Vector(size_t initialCapacity) : array(new T[initialCapacity]), capacity(initialCapacity), size(0) {}

    // Конструктор копирования
    Vector(const Vector& other) : capacity(other.capacity), size(other.size) {
        array = new T[capacity];
        for (size_t i = 0; i < size; ++i) {
            array[i] = other.array[i];
        }
    }

    // Оператор присваивания
    Vector& operator=(const Vector& other) {
        if (this != &other) {
            delete[] array;
            capacity = other.capacity;
            size = other.size;
            array = new T[capacity];
            for (size_t i = 0; i < size; ++i) {
                array[i] = other.array[i];
            }
        }
        return *this;
    }

    // Деструктор
    ~Vector() {
        delete[] array;
    }

    // Добавление элемента в конец массива
    void push_back(const T& value) {
        if (size >= capacity) {
            // Увеличиваем емкость массива в два раза, если не хватает места
            capacity = (capacity == 0) ? 1 : capacity * 2;
            T* newArray = new T[capacity];
            for (size_t i = 0; i < size; ++i) {
                newArray[i] = array[i];
            }
            delete[] array;
            array = newArray;
        }
        array[size++] = value;
    }

    // Доступ к элементу по индексу
    T& operator[](size_t index) {
        if (index >= size) {
            throw;
        }
        return array[index];
    }

    // Возвращает текущий размер массива
    size_t getSize() const {
        return size;
    }

    // Проверяет, пуст ли массив
    bool empty() const {
        return size == 0;
    }
};

использование:
struct SNetHitInfo {
    SNetHitInfo(unsigned int targetId, int material, int type, int partId, Math::Vec3 pos, float damageReduction, BYTE profilerId)
        : targetId(targetId), material(material), typeId(type), partId(partId), pos(pos), damageReduction(damageReduction), profilerId(profilerId) {}
    unsigned int targetId; // 0x00
    int material; // 0x04
    int typeId; // 0x08
    int partId; // 0x0C
    Math::Vec3 pos; // 0x10
    float damageReduction; // 0x1C
    BYTE profilerId; // 0x20
};
struct SShootInfo {
    SShootInfo(unsigned int projectileId, Vector<SNetHitInfo> hits) : projectileId(projectileId), hits(hits) {}
    unsigned int projectileId;  // 0x00
    DWORD dw1;  // 0x04
    Vector<SNetHitInfo> hits; // 0x08
};

struct SRequestShootHit {
    Math::Vec3 shootPos;  // 0x00
    int predictionHandle; // 0x0C
    Math::Vec3 dir; // 0x10
    BYTE profilerId; // 0x1C
    Vector<SShootInfo> shoots; // 0x20
    unsigned int shooterId; // 0x38
    unsigned int itemId; // 0x3C
};

SRequestShootHit m_request;
void AddProjectile(unsigned int projectileId, Vector<SNetHitInfo> hits) {
    m_request.shoots.push_back(SShootInfo(projectileId, hits));
}
Ошибка:
2024-03-31_02-11-31.png

Строка с ошибкой:

C++:
T* newArray = new T[capacity];
 
OG
Забаненный
Статус
Оффлайн
Регистрация
5 Ноя 2021
Сообщения
18
Реакции[?]
4
Поинты[?]
4K
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Попробуй вместо new[] через malloc сделать(у меня через раз получается), либо попробуй указать на объект, вместо самого объекта
 
Пользователь
Статус
Оффлайн
Регистрация
5 Июл 2022
Сообщения
1,001
Реакции[?]
86
Поинты[?]
23K
Попробуй вместо new[] через malloc сделать(у меня через раз получается), либо попробуй указать на объект, вместо самого объекта
Ну а хуй разница это во первых. Во вторых, я же написал, что программа без crt. Или ты имеешь ввиду использовать самописный malloc?
 
I Want to Die in New Orleans
Участник
Статус
Оффлайн
Регистрация
10 Окт 2020
Сообщения
514
Реакции[?]
495
Поинты[?]
84K
чувак, тебе же компилятор прямо таки пишет - "Я не могу найти и использовать конструктор без параметров", конструктор по умолчанию требуется для создания элементов типа T, когда новые элементы создаются без явного указания параметров конструктора. так как у тебя есть конструктор с параметрами, а параметры ты при создании не передаёшь - этот конструктор НЕ используется, поэтому компилятор попытается найти дефолтный конструктор твоего класса/структуры, но не сможет этого сделать потому что при объявлении "пользовательского" конструктора, компилятор не станет генерировать конструктор по умолчанию (в этом случае тебе нужно явно объявить и разрешить использование конструктора по умолчанию при помощи конструкции class_name() = default)

spoonfeed:
C++:
struct SShootInfo {
    SShootInfo() : projectileId(0), dw1(0) {} // `hits` initialized by default `Vector` constructor
    SShootInfo(unsigned int projectileId, Vector<SNetHitInfo> hits) : projectileId(projectileId), hits(hits) {}
    unsigned int projectileId;  // 0x00
    DWORD dw1;  // 0x04
    Vector<SNetHitInfo> hits; // 0x08
};
 
Пользователь
Статус
Оффлайн
Регистрация
5 Июл 2022
Сообщения
1,001
Реакции[?]
86
Поинты[?]
23K
чувак, тебе же компилятор прямо таки пишет - "Я не могу найти и использовать конструктор без параметров", конструктор по умолчанию требуется для создания элементов типа T, когда новые элементы создаются без явного указания параметров конструктора. так как у тебя есть конструктор с параметрами, а параметры ты при создании не передаёшь - этот конструктор НЕ используется, поэтому компилятор попытается найти дефолтный конструктор твоего класса/структуры, но не сможет этого сделать потому что при объявлении "пользовательского" конструктора, компилятор не станет генерировать конструктор по умолчанию (в этом случае тебе нужно явно объявить и разрешить использование конструктора по умолчанию при помощи конструкции class_name() = default)

spoonfeed:
C++:
struct SShootInfo {
    SShootInfo() : projectileId(0), dw1(0) {} // `hits` initialized by default `Vector` constructor
    SShootInfo(unsigned int projectileId, Vector<SNetHitInfo> hits) : projectileId(projectileId), hits(hits) {}
    unsigned int projectileId;  // 0x00
    DWORD dw1;  // 0x04
    Vector<SNetHitInfo> hits; // 0x08
};
Слушай, вопрос такой. Можно как нить разрешить 1 импорт? При отключении импортов, оно не дает их использовать. Можно ли как то "разрешить" один?
 
I Want to Die in New Orleans
Участник
Статус
Оффлайн
Регистрация
10 Окт 2020
Сообщения
514
Реакции[?]
495
Поинты[?]
84K
Слушай, вопрос такой. Можно как нить разрешить 1 импорт? При отключении импортов, оно не дает их использовать. Можно ли как то "разрешить" один?
Хз, в таком случае тебе нужно в процессе иметь уже загруженный модуль который будет иметь в EAT эту функцию, и все что нужно сделать это найти адрес этого самого экспорта и вызвать его в рантайме передав все нужные аргументы. Как это сделать при помощи "разрешения" импорта для компилятора - хз, я не думаю что это реально, и весь твой проект "без импортов" потеряет свой смысл

P.S это все мое представление на бумаге, сам я с таким не сталкивался. был бы рад увидеть ответ от сильных в этом вопросе ребят
 
Сверху Снизу