заменить оператор new на malloc

0

Я пытаюсь заменить оператор new и удалить с помощью malloc и бесплатно (у меня есть причины для этого). Проблема приведена в коде ниже:

std::string *temp = (std::string *)malloc(sizeof(std::string) * 2); // allocate space for two string objects.
temp[0] = "hello!";
temp[1] = "world!";
for(int i = 0; i < 2; i++)
{
    printf("%s\n", temp[i].c_str());
}
free(temp);
return 0; // causes SIGSEGV.

Однако..

std::string *temp = new std::string[2];
temp[0] = "hello!";
temp[1] = "world!";
for(int i = 0; i < 2; i++)
{
    printf("%s\n", temp[i].c_str());
}
delete [] temp;
return 0; // works fine

Зачем? и может ли кто-нибудь предложить мне, что это правильный способ заменить этих операторов malloc и бесплатно?

С уважением.

EDIT: это просто пример, я не использую стандартную библиотеку C++.

EDIT: как насчет этого?

class myclass
{
    public:
        myclass()
        {
            this->number = 0;
        }
        myclass(const myclass &other)
        {
            this->number = other.get_number();
        }
        ~myclass()
        {
            this->number = 0;
        }
        int get_number() const
        {
            return this->number;
        }
        void set_number(int num)
        {
            this->number = num;
        }
    private:
        int number;
};

int main(int argc, char *argv[])
{
    myclass m1, m2;
    m1.set_number(5);
    m2.set_number(3);

    myclass *pmyclass = (myclass *)malloc(sizeof(myclass) * 2);

    pmyclass[0] = myclass(m1);
    pmyclass[1] = myclass(m2);

    for(int i = 0; i < 2; i++)
    {
        printf("%d\n", pmyclass[i].get_number());
        pmyclass[i].myclass::~myclass();
    }

    free(pmyclass);

    return 0;
}
Теги:
operator-overloading
memory

3 ответа

2
Лучший ответ

Вы хотите реализовать собственный operator new() с помощью malloc, а не для замены operator new на malloc.

Чтобы реализовать operator new(), просто напишите его так же, как и с любой другой функцией.

void* operator new() (size_t sz) { return malloc(sz); }

Если вы хотите стандартную версию, которая бросает std::bad_alloc при сбое, просто вставьте свой код для этого.

operator delete остается как упражнение для читателя, и поэтому operator new[]() и operator delete[]().

  • 0
    Это то, что я пытаюсь, но функция, которую вы предоставили, не вызывает конструктор объекта.
  • 0
    @ OvérFlôwz: он не имеет и не должен иметь дело с объектами и их конструкторами. Его задача - выделить память. Конструкторы вызываются при использовании оператора new, который отличается от оператора new () .
Показать ещё 5 комментариев
7

malloc и free не вызывают конструктор и деструктор классов C++. Он также не хранит информацию о количестве элементов, выделенных в массиве (например, вы делаете). Это означает, что память просто назначается, но никогда не инициализируется. Однако вы все же можете вручную сконструировать и уничтожить объект.

Вы должны начать с создания объекта, используя place-new. Это требует, чтобы вы передали указатель на место, где должен быть создан объект, и указать тип объекта, который должен быть создан. Например, первая строка, в которой вы назначаете строковый литерал для выделенного (но неинициализированного) строкового объекта, выглядит следующим образом:

new(&temp[0]) std::string("hello!");

Как только вы закончите со строками, вам нужно уничтожить их, вызвав их деструктор напрямую.

temp[0].std::string::~string();

Код, который вы задали, будет выглядеть примерно так:

// allocate space for two string objects.
std::string *temp = (std::string *)malloc(sizeof(std::string) * 2); 

// Using placement-new to constructo the strings
new(&temp[0]) std::string("hello!");
new(&temp[1]) std::string("world!");

for (int i = 0; i < 2; i++)
{
    printf("%s\n", temp[i].c_str());
}

//  Destroy the strings by directly calling the destructor
temp[0].std::string::~string();
temp[1].std::string::~string();
free(temp);
  • 0
    Оператор new находится в стандартной библиотеке C ++, как я уже сказал, я не использую его, +1 за упоминание ручного уничтожения.
  • 0
    Я просто пытаюсь найти способ, который будет реализовывать операторы new и delete без использования стандартной библиотеки C ++, а только стандартной библиотеки C. какие-либо предложения?
4

Если вы действительно хотите спуститься в эту кроличью нору... ну, вам нужно место новое, и вам нужно вызвать деструкторов вручную. Вот как это выглядит:

#include <string>
#include <stdlib.h>
#include <stdio.h>

int main()
{
    std::string *temp = (std::string *)malloc(sizeof(std::string) * 2); // allocate space for two string objects.
    new (&temp[0]) std::string("hello!");
    new (&temp[1]) std::string("world!");
    for(int i = 0; i < 2; i++)
    {
        printf("%s\n", temp[i].c_str());
    }
    temp[1].std::string::~string();
    temp[0].std::string::~string();
    free(temp);
    return 0;
}

Поскольку malloc предоставляет вам неинициализированный блок памяти, вам нужно построить объекты в соответствующих слотах памяти и, прежде чем освобождать память, вы должны вручную их уничтожить.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню