C++17: new с выравниванием - как удалять по феншую?
От: Mr.Delphist  
Дата: 25.12.18 17:55
Оценка: 15 (2)
Вылезла такая закавыка. Создаю динамически инстансы, но не просто так, а с выравниванием:
auto p = new(std::align_val_t(64)) std::string();

// что-то делаем с p

delete p;


Но с удалением какая-то беда есть — MinGW крашится на "Unknown signal". Вопрос: это сам компилер кривой пока что, или надо как-то по особому удалять выровненный указатель? Кто сталкивался? Народ в гуглении говорит надо как-то выпендрануто через operator new и operator delete всё делать, но сомнения гложут.
Re: C++17: new с выравниванием - как удалять по феншую?
От: watchmaker  
Дата: 25.12.18 19:54
Оценка: 16 (1) +1
Здравствуйте, Mr.Delphist, Вы писали:

MD>или надо как-то по особому удалять выровненный указатель?

Считай, что это отдельное семейство парных функций, подобно уже существующим malloc/free, new/delete и new[]/delete[]. Так если ты выделил память через new[], а освободил через free, то это ошибка в программе и её работоспособность не гарантируется.


MD>Кто сталкивался? Народ в гуглении говорит надо как-то выпендрануто через operator new и operator delete всё делать, но сомнения гложут.

Компилятор сам способен выбрать нужные методы создания и освобождения памяти, если это описать в типе и не мешать.
Например:
struct alignas(1024) S {};

auto* p = new S; // вызовет new с выравниванием
delete p; // вызовет delete с выравниванием


Ты же в своём коде явно указываешь другую функцию выделения памяти, а не ту, которую хочет выбрать компилятор, а потом ещё и теряешь эту информацию. Собственно, если хочется дальше вручную тут этим управлять, то нужно также самому вручную доставить до delete и аргумент align_val_t, который был передан в new при выделении.
Re: C++17: new с выравниванием - как удалять по феншую?
От: reversecode google
Дата: 25.12.18 20:21
Оценка: 14 (1)
http://www.cppstd17.com/code/lang/tracknew.cpp.html
http://www.cppstd17.com/code/lang/tracknew.hpp.html
Re: C++17: new с выравниванием - как удалять по феншую?
От: Vamp Россия  
Дата: 26.12.18 02:03
Оценка:
MD>Но с удалением какая-то беда есть — MinGW крашится на "Unknown signal". Вопрос: это сам компилер кривой пока что, или надо как-то по особому удалять выровненный указатель? Кто сталкивался? Народ в гуглении говорит надо как-то выпендрануто через operator new и operator delete всё делать, но сомнения гложут.

Ну ответ уже дали, но по сути это достаточно очевидно, что нужна парная функция. Как работает alignment new в принципе? Он выделяет блок большего размера, и возвращает адрес внутри этого блока, соответствующим образом выровненный. Как мы помним, функции удаления памяти нужна дополнительная информация о выделенном блоке. Традиционно эта информация хранится в специальном объекте, расположенном непосредственно перед выделенным блоком. В случае выравненного выделения памяти, указатель возвращенный в вызывающий код, указывает не на начало блока, а где-то внутри него. Соответственно, удаляющая функция доожна найти начало блока, используя информацию о выравнивании.
Да здравствует мыло душистое и веревка пушистая.
Re[2]: C++17: new с выравниванием - как удалять по феншую?
От: night beast СССР  
Дата: 26.12.18 06:26
Оценка:
Здравствуйте, Vamp, Вы писали:

MD>>Но с удалением какая-то беда есть — MinGW крашится на "Unknown signal". Вопрос: это сам компилер кривой пока что, или надо как-то по особому удалять выровненный указатель? Кто сталкивался? Народ в гуглении говорит надо как-то выпендрануто через operator new и operator delete всё делать, но сомнения гложут.


V>Ну ответ уже дали, но по сути это достаточно очевидно, что нужна парная функция.


если не ошибаюсь, парный нестандартный delete вызывается при исключении при конструировании объекта с соответствующим new.
как понял из описания, версия с std::align_val_t из delete-выражения будет вызвана только для типов (не объектов), у которых выравнивание больше __STDCPP_DEFAULT_NEW_ALIGNMENT__
Re[2]: C++17: new с выравниванием - как удалять по феншую?
От: Mr.Delphist  
Дата: 26.12.18 11:09
Оценка:
Здравствуйте, Vamp, Вы писали:

V>Ну ответ уже дали, но по сути это достаточно очевидно, что нужна парная функция.


Но вот КАК это правильно сказать на 17 плюсе? Тема новая, гугл ещё не наелся.

auto p = new(std::align_val_t(64)) std::string();

...

delete (std::align_val_t(64)) p; // error: type 'enum class std::align_val_t' argument given to 'delete', expected pointer

delete (std::align_val_t(64), p); // warning: left operand of comma operator has no effect [-Wunused-value]

delete (p, std::align_val_t(64)); // warning: left operand of comma operator has no effect [-Wunused-value]
                                  // error: type 'enum class std::align_val_t' argument given to 'delete', expected pointer
Re[2]: C++17: new с выравниванием - как удалять по феншую?
От: Mr.Delphist  
Дата: 26.12.18 11:10
Оценка:
Здравствуйте, watchmaker, Вы писали:

W>Например: [ccode]struct alignas(1024) S {};


Не-не, я про случай если без использования alignas. Чтобы явно дёргать new/delete с указанием выравнивания.
https://rsdn.org/forum/cpp/7334025.1
Автор: Mr.Delphist
Дата: 26.12.18
Re[3]: C++17: new с выравниванием - как удалять по феншую?
От: night beast СССР  
Дата: 26.12.18 11:12
Оценка:
Здравствуйте, Mr.Delphist, Вы писали:

V>>Ну ответ уже дали, но по сути это достаточно очевидно, что нужна парная функция.


MD>Но вот КАК это правильно сказать на 17 плюсе? Тема новая, гугл ещё не наелся.


operator delete(pl, std::align_val_t(64));
Re[4]: C++17: new с выравниванием - как удалять по феншую?
От: Mr.Delphist  
Дата: 26.12.18 12:39
Оценка:
Здравствуйте, night beast, Вы писали:

NB>
NB>operator delete(pl, std::align_val_t(64));
NB>


Вот это и смущает, неужели нет ничего менее многословного? Типа delete (X, A). Ведь для new такой вариант есть.
Re[5]: C++17: new с выравниванием - как удалять по феншую?
От: watchmaker  
Дата: 26.12.18 12:49
Оценка: +1
Здравствуйте, Mr.Delphist, Вы писали:

MD>Вот это и смущает, неужели нет ничего менее многословного? Типа delete (X, A).

Остановись: ты делаешь нечто немного странное и используешь фичу не так, как она задумывалась к использованию
Да, язык позволяет это сделать, но это всё равно не предполагается к повсеместному применению в программах.
То, что вызов функции удаления выглядит уродливо, — следствие именно этого. Никто не ожидает, что этот вызов появится где-то в программе (за пределами всяких глубоких системных библиотек), поэтому и красивой обёртки у него нет

Впрочем, такую обёртку можно написать самому: заверни код по выделению и освобождению памяти со своей стратегией в умный указатель и используй его. Да и вообще, использование умных указателей часто предпочтительнее ручного управления вызовами new и delete.
Отредактировано 26.12.2018 12:53 watchmaker . Предыдущая версия .
Re[6]: C++17: new с выравниванием - как удалять по феншую?
От: Vamp Россия  
Дата: 26.12.18 13:40
Оценка: +1
W>То, что вызов функции удаления выглядит уродливо, — следствие именно этого. Никто не ожидает, что этот вызов появится где-то в программе (за пределами всяких глубоких системных библиотек), поэтому и красивой обёртки у него нет

Чистая правда. Выравнивание — это свойство типа, а не выделения памяти. Почему выравнивание при динамичеком выделении должно отличаться от автоматического?

W>Впрочем, такую обёртку можно написать самому: заверни код по выделению и освобождению памяти со своей стратегией в умный указатель и используй его. Да и вообще, использование умных указателей часто предпочтительнее ручного управления вызовами new и delete.

Часто? Я бы сказал, всегда )
Да здравствует мыло душистое и веревка пушистая.
Re[7]: C++17: new с выравниванием - как удалять по феншую?
От: rg45 СССР  
Дата: 26.12.18 14:41
Оценка:
Здравствуйте, Vamp, Вы писали:

W>>Впрочем, такую обёртку можно написать самому: заверни код по выделению и освобождению памяти со своей стратегией в умный указатель и используй его. Да и вообще, использование умных указателей часто предпочтительнее ручного управления вызовами new и delete.


V>Часто? Я бы сказал, всегда )


Ты, наверное, не видел это: http://rsdn.org/forum/cpp/7326186.1
Автор: Sheridan
Дата: 17.12.18
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[8]: C++17: new с выравниванием - как удалять по феншую?
От: Vamp Россия  
Дата: 26.12.18 15:15
Оценка:
V>>Часто? Я бы сказал, всегда )

R>Ты, наверное, не видел это: http://rsdn.org/forum/cpp/7326186.1
Автор: Sheridan
Дата: 17.12.18


Ну и зачем я это увидел теперь? )) Впрочем, это же Шеридан.
Да здравствует мыло душистое и веревка пушистая.
Re[7]: C++17: new с выравниванием - как удалять по феншую?
От: Mr.Delphist  
Дата: 26.12.18 15:30
Оценка:
Здравствуйте, Vamp, Вы писали:

V>Выравнивание — это свойство типа, а не выделения памяти. Почему выравнивание при динамичеком выделении должно отличаться от автоматического?


Хммм… Т.е. если у меня есть указатель на класс C, то почему-то мне может быть недоступно выбрать как именно саллоцировать туда память каждый раз? Скажем, чтобы каждый чётный прогон цикла — была выровненная память, а каждый нечётный — дефолтная? Или вообще написать цикл, где на каждом повторении шаг выравнивания для аллокации растёт по степени двойки? Например:

for(int i = 1; i < 10; ++i)
{
    auto p = new(std::align_val_t(std::pow(2,i))) std::string(); // если так можно...
    ...
    delete(std::align_val_t(std::pow(2,i))) p; // ... то почему так нельзя?
}
Re[8]: C++17: new с выравниванием - как удалять по феншую?
От: Vamp Россия  
Дата: 26.12.18 16:33
Оценка: +1 -1
Здравствуйте, Mr.Delphist, Вы писали:

MD>Хммм… Т.е. если у меня есть указатель на класс C, то почему-то мне может быть недоступно выбрать как именно саллоцировать туда память каждый раз? Скажем, чтобы каждый чётный прогон цикла — была выровненная память, а каждый нечётный — дефолтная? Или вообще написать цикл, где на каждом повторении шаг выравнивания для аллокации растёт по степени двойки? Например:


Потому что твой юзкейс (чтобы было!) не является приоритетным для авторов стандарта.
Да здравствует мыло душистое и веревка пушистая.
Re[4]: C++17: new с выравниванием - как удалять по феншую?
От: Erop Россия  
Дата: 27.12.18 20:45
Оценка:
Здравствуйте, night beast, Вы писали:

MD>>Но вот КАК это правильно сказать на 17 плюсе? Тема новая, гугл ещё не наелся.


NB>
NB>operator delete(pl, std::align_val_t(64));
NB>


А разве это позовёт деструктор?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[5]: C++17: new с выравниванием - как удалять по феншую?
От: Erop Россия  
Дата: 27.12.18 20:47
Оценка:
Здравствуйте, Mr.Delphist, Вы писали:

MD>Вот это и смущает, неужели нет ничего менее многословного? Типа delete (X, A). Ведь для new такой вариант есть.


Можно шаблонную функцию написать, или класс...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[5]: C++17: new с выравниванием - как удалять по феншую?
От: night beast СССР  
Дата: 27.12.18 21:01
Оценка: -1
Здравствуйте, Erop, Вы писали:

E>А разве это позовёт деструктор?


нет, но вроде вопрос был не в этом
Re[6]: C++17: new с выравниванием - как удалять по феншую?
От: Erop Россия  
Дата: 27.12.18 22:02
Оценка:
Здравствуйте, night beast, Вы писали:

E>>А разве это позовёт деструктор?


NB>нет, но вроде вопрос был не в этом


Оригинальная конструкция вроде как звала...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[7]: C++17: new с выравниванием - как удалять по феншую?
От: night beast СССР  
Дата: 28.12.18 04:36
Оценка:
Здравствуйте, Erop, Вы писали:

E>>>А разве это позовёт деструктор?


NB>>нет, но вроде вопрос был не в этом


E>Оригинальная конструкция вроде как звала...


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