Comments 15
К сожалению, не понял из статьи, зачем в рассматриваемом кейсе именно неуправляемый массив.
Один из подводных камней, видимо, выравнивание полей в структурах.
Мне так показалось, что это всё скорее нужно для сопряжения с кодом на Си, для написания над ним безопасных оберток. А ещё мне кажется, что лучше бы разрешали пользоваться такими штуками внутри блока unsafe, а то сейчас по коду:
Становится неясно безопасно у нас всё или нет (мало ли кто решил обозвать свойство именем memory). Итого этот UnsafeMutablePointer может радостно по всему коду расползтись.
let pSize = UnsafeMutablePointer<GifSize>(p)
// пусть тут будет 10000 строчек ещё
NSLog("Gif width = \(pSize.memory.width), height = \(pSize.memory.height)")
Становится неясно безопасно у нас всё или нет (мало ли кто решил обозвать свойство именем memory). Итого этот UnsafeMutablePointer может радостно по всему коду расползтись.
Да, вы правы если pSize будет иметь время жизни большее чем data то это приведет к чтению освобожденной памяти. Так что применяя указатели нужно быть очень внимательным.
Поэтому в Rust указатели могут быть использованы только внутри unsafe блока, а если они там были объявлены, то они его и покинуть не смогут. То есть ногу прострелить становится сложнее.
> в Rust указатели могут быть использованы только внутри unsafe блока
Смотря как понимать «использованы» — сырые указатели можно брать и передавать где угодно, вот разыменовать можно только в `unsafe{}`.
> а если они там были объявлены, то они его и покинуть не смогут
Не, сырые указатели можно куда угодно передавать же, в том числе и из блока:
https://play.rust-lang.org/?gist=17f0da2b3d478e51e0b7&version=stable
Смотря как понимать «использованы» — сырые указатели можно брать и передавать где угодно, вот разыменовать можно только в `unsafe{}`.
> а если они там были объявлены, то они его и покинуть не смогут
Не, сырые указатели можно куда угодно передавать же, в том числе и из блока:
https://play.rust-lang.org/?gist=17f0da2b3d478e51e0b7&version=stable
В Java для ускорения критически важных участков кода используют. Быть может, и тут получится.
Могли бы вы пояснить на каком-то другом примере преимущества от подобных операций — на чем реально можно много сэкономить ресурсов.
Просто в данном случае размер картинки, конечно, удалось получить без каких-либо сторонних библиотек, но для другого программиста данный код в проекте может вызвать больше вопросов. Тут выгода не так очевидна, на мой взгляд.
Просто в данном случае размер картинки, конечно, удалось получить без каких-либо сторонних библиотек, но для другого программиста данный код в проекте может вызвать больше вопросов. Тут выгода не так очевидна, на мой взгляд.
let p = UnsafeMutablePointer<Int>.alloc(1) p.memory = 20 p.dealloc(1)
Во второй строчке следует использовать метод initialize(), так как память ещё не инициализирована. Только после этого можно работать с memory. До того, как освобождать память, следует вызвать метод destroy().
Память, на которую указывает Unsafe(Mutable)Pointer, может быть инициализирована или нет. Очень важно использовать правильные методы для памяти в различных состояниях. Так как ваш указатель указывает на Int, то скорее всего в этом конкретном случае ничего плохого не случится, но как только вы начнёте работать с типами, для которых копия экземпляра не создаётся тривиальным побитовым копированием, не использование правильных методов почти наверняка приведёт к падениям программы и утечкам памяти. Посмотрите документацию на UnsafeMutablePointer, там довольно подробно написано про состояния, в которых он может находиться.
Тем не менее подобный низкоуровневый код в некоторых случаях позволяет оптимизировать программу либо по скорости, либо по количеству используемой памяти.
Чаще всего прямая работа с указателями нужна для вызова API на C, которые принимают сложные структуры данных с указателями внутри.
Sign up to leave a comment.
Unsafe в Swift