Pull to refresh

Comments 15

К сожалению, не понял из статьи, зачем в рассматриваемом кейсе именно неуправляемый массив.
Если имеется ввиду чтение GIF хедера то непосредственно «неуправляемого» массива там нет, есть набор байт который управляется объектом типа NSData, я же описал как с помощью указателей интерпретировать данные из этого массива (в данном случае как строку и структуру с двумя целыми числами)
Один из подводных камней, видимо, выравнивание полей в структурах.
Верно, как следствие от выравнивания наличие минимального расстояния в массиве структур между структурами которое в общем случаем может не совпадать с размером структуры.
UFO landed and left these words here
Да, вы правы если pSize будет иметь время жизни большее чем data то это приведет к чтению освобожденной памяти. Так что применяя указатели нужно быть очень внимательным.
UFO landed and left these words here
> в Rust указатели могут быть использованы только внутри unsafe блока

Смотря как понимать «использованы» — сырые указатели можно брать и передавать где угодно, вот разыменовать можно только в `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, которые принимают сложные структуры данных с указателями внутри.
initialize() и destroy() предназначены для работы с объектами, для основных типов они ничего не делают. Впрочем вы правы, стоит поправить, чтобы не возникало недопонимания.
Существует контракт API, который описан в документации. Если его не выполнять, а просто написать код и заметить что и так, кажется, работает, то это просто везение. Кроме того, в будущем может сломаться.
В общем случае абсолютно согласен!
Sign up to leave a comment.

Articles