разве не записывает в какую то таблицу, что вот я выделил по началу этого участка памяти столько то байт, если потом сделать delete этому указателю, по идее тому кто память освобождает должно быть без разницы какого типа этот указатель, он просто смотрит сколько он выделил байт ранее. Разве не так? Я где то читал, что когда работает delete Он берет еще откуда то служебную информацию сколько было выделено. Получается ему без разницы хоть ты сделаешь delete указателю на void. Это были мои мысли вслух, допускаю, что я не прав, но просто интересно, к то в теме прокомментируйте, пожалуйста.
Оберните код в теги: 3 символа ` до и после кода (в случае одиночной конструкции достаточно 1 ` с обеих сторон). Спасибо!
передача указателя куда либо уже не безопасно, потому что с этим указателем можно делать все что угодно, включая и delete. Если после делита обратится по указателю, то это уб, конечная. Поэтому лучше использовать умный указатель для такого, шаред птр следит сколько есть владельцев у указателя и сам его уничтожает, когда владельцев становится 0
Это понятно. Я про факт отдачи этого участка памяти обратно системе. Интересно как это работает, он смотрит какой тип когда делает delete или смотрит сколько байт освободить в какой то своей таблице
да, делит нормально отработает, просто в месте где ты сделал new останется указатель на то, что ты высвободил 🌚
или ты передал этот указатель в 2 обьекта, и во втором обьекте тоже будет "провисший" указатель
Это понятно, да. Обычно еще после delete лучше подстраховатьтся и присвоить указателю nullptr, тогда ты потом проверяешь на nullptr и понимаешь этот указатель не надо использовать.
а это уже фокусы и подражание умному указателю, который уже придуман и доступен для использования
Если я этот указатель много куда скопировал до этого, то да, это плохо! Лучше так не делать!
Я кажется понял как это работает. Если мы сделаем new Производный класс и положим его в указатель базового класса (или даже просто в указатель на void), то в принципе, когда мы сделаем delete этому указателю, то сама память то освободится. Проблема то более тонкая, дело в том, что в этом куске памяти могли храниться указатели, которые, в свою очередь могли указывать на другие куски памяти в куче. То есть нам недостаточно просто взять и удалить кусок памяти, который занимают члены. Нам надо удалить все куски памяти, на которые могут ссылаться члены. Именно для этого и нужны деструкторы, а виртуальный деструктор нужен, чтоб не просто очистить память занимаемую членами, а заставить как у базового, так и у производного класса, если у него есть в составе указатели, то чтоб вызвался его деструктор тоже, что в свою очередь вызовет очистку тех участков памяти, на которые ссылаются члены-указатели производного класса.
Теперь осталось про умные указатели прочитать и new / delete будет не нужен.
Кто сказал что освободиться вся память?
Я сначала подумал, что ты неправ. Через какое то время, я осознал, что ты прав, от new можно отказаться, а использовать make функции, что возвращают указатель, положенный внутрь умного указателя.
Не можно, а нужно. new нужен только в двух случаях: для placement и для нестандартных параметров типа выравнивания больше, чем требуют размещаемые в динамической памяти объекты. Для всего остального всегда make_smartpointer функции.
Обсуждают сегодня