Разыменование указателя в Julia (unsafe_load(ptr) работает, но unsafe_wrap(Array, ptr, 1) segfaults)

#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 она случайно верна?