Использование placement new, malloc и free

#c #malloc #free #destructor #placement-new

#c #malloc #Бесплатно #деструктор #размещение-новое

Вопрос:

В принципе, у меня есть блок памяти, выделенный с помощью malloc, в который я хочу начать размещать объекты с помощью placement new. Я знаю, что деструкторы для этих объектов должны быть явно вызваны, когда я их удаляю, но я хочу убедиться, что я полностью понимаю это и что я делаю это правильно. Я почти наверняка откажусь от этого подхода и буду действовать более простым способом, но я решил, что попрошу просто для понимания.

У меня есть класс WordIndex, который содержит следующие закрытые переменные-члены:

 struct Word
{
    std::string word;
    std::vector<unsigned int> index;
};

Word* m_words;
std::string* m_lines;
 

Память выделяется / перераспределяется для обоих указателей с помощью malloc / realloc, а объекты создаются с использованием следующего кода (они не перезаписывают какие-либо ранее существовавшие объекты):

 new (amp;m_words[pos]) Word();
new (amp;m_lines[m_numoflines]) std::string();
 

У меня есть деструктор следующим образом, но я почти на 100% уверен, что он работает неправильно, несмотря на отсутствие каких-либо ошибок при запуске.

 WordIndex::~WordIndex()
{
    unsigned int i;
    for( i = 0; i < m_numofwords; i  )
    {
        m_words[i].~Word();
    }

    free(m_words);
    free(m_lines);
}
 

Мои вопросы заключаются в следующем:

  1. Учитывая, что Word struct имеет вектор, достаточно ли просто вызвать ~Word , или мне нужно заранее вызвать деструктор для вектора отдельно?
  2. Нужно ли мне вызывать деструктор для строки (как для m_lines, так и для Word.word), и если да, то как мне это сделать? Похоже, у него нет функции, подобной ~string, которую я могу вызвать.
  3. Я пропустил что-нибудь еще? Я совершенно уверен, что у меня есть.

Заранее спасибо!

Ответ №1:

  1. Учитывая, что Word struct имеет вектор, достаточно ли просто вызвать ~Word , или мне нужно заранее вызвать деструктор для вектора отдельно?

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

  1. Нужно ли мне вызывать деструктор для строки (как для m_lines, так и для Word.word), и если да, то как мне это сделать? Похоже, у него нет функции, подобной ~string, которую я могу вызвать.

Да, вы делаете. Деструктор должен быть там, он typedef basic_string отредактирован, поэтому вы должны вызывать ~basic_string() его.

  1. Я пропустил что-нибудь еще? Я совершенно уверен, что у меня есть.

Деструктор для string .

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

Комментарии:

1. Разве это не string typedef for basic_string<...> ?

2. Потрясающе, спасибо! Можете ли вы привести пример вызова деструктора строк, поскольку что-то вроде m_lines[0] .~string(); кажется, недопустимо. РЕДАКТИРОВАТЬ: я только что заметил, что ~basic_string() ДЕЙСТВИТЕЛЬНО существует, так что, возможно, это правильный деструктор для вызова.

3. @jcptopi — добавлен в текст

4. Хорошо, просто для ясности, мне нужно только вызвать ~basic_string() для строк в m_lines , поскольку ~Word() вызовет его для строки внутри структуры, правильно?

5. @jcptopi — вам нужно вызвать дескриптор для любого конструктора, который вы вызывали аналогичным образом. В вашем случае это все строки в m_lines.

Ответ №2:

Единственное, чего вам не хватает, это вызова всех деструкторов string s ‘. Он вызывается ~basic_string ( string на самом деле это просто typedef for basic_string с некоторыми параметрами шаблона).

Нет, вам не нужно вызывать деструкторы vector s ‘, потому что они вызываются деструктором, предоставляемым компилятором для вашей Word структуры.