#pointers #julia #dereference
#указатели #джулия #разыменование
Вопрос:
Я пытаюсь разыменовать указатель с unsafe_load
помощью and unsafe_wrap
. Я обнаружил, что unsafe_load
это работает просто отлично, однако unsafe_wrap
сбой в случае разыменования указателя на изменяемую структуру. Пример игрушки:
[mutable] struct Wrapper
data::Int
end
some = Wrapper(1)
ptr = convert(Ptr{Wrapper}, Base.Libc.malloc(sizeof(Wrapper)))
unsafe_store!(ptr, some)
unsafe_load(ptr) # returns Wrapper(1)
unsafe_wrap(Array, ptr, 1) # segfaults if Wrapper is mutable, works fine if not
И мне нужно именно unsafe_wrap
так, как это не создает копию (мне нужно выполнить некоторые операции на месте в выделенной malloc
памяти). Почему это происходит по умолчанию?
Ответ №1:
Нашел ответ здесь
Вектор изменяемых структур — это вектор указателей, т.е.
mutable struct Wrapper
data::Int
end
a = Wrapper(1)
b = [a, a]
a.data = 2
b # is now Wrapper[Wrapper(2), Wrapper(2)]
Таким образом, расположение памяти Int
и Wrapper
не совпадают.
Комментарии:
1. Я собирался прокомментировать, что подозревал, что проблема заключается в том, что
sizeof
подсчитываются размеры полей независимо от того, является ли структура изменяемой или нет, поэтому ее нельзя использовать для поиска памяти, которую структура занимает в качестве векторного элемента или другого поля структуры, такого какPtr
поле . Однако затем у меня возникла мысль: указатели имеютInt
размер, поэтомуsizeof
, по-видимому, случайно верны, потому что поля вашей структуры такжеInt
имеют размер. Не могли бы вы объяснить, как происходит ошибка segfault, еслиmalloc
она случайно верна?