gpt4 book ai didi

julia - Julia 字符串文字的生命周期是多少

转载 作者:行者123 更新时间:2023-12-04 13:26:23 26 4
gpt4 key购买 nike

例如,在 Julia session 结束之前使用 foo 返回的指针是否安全?在这种情况下, foobar 之间没有区别,对吧?

foo(s::String="foo") = Base.unsafe_convert(Ptr{UInt8}, Base.cconvert(Ptr{UInt8}, s))
bar() = Base.unsafe_convert(Ptr{UInt8}, Base.cconvert(Ptr{UInt8}, "foo"))
编辑:
我想添加更多背景信息。我正在尝试连接 C++ 库中的一些方法,该库具有默认为 C++ 字符串文字的默认参数值。派生指针用作“引用”(请参阅​​下面的链接)。在 C++ 中只使用文字似乎没问题,我想知道在 Julia 中这样做的最佳方法是什么。 (我不认为 GC.@preserve 是一个好的解决方案,因为很难知道何时可以安全地对资源进行 GC 处理。)
X-ref: Is it safe to init `StringRef` with a string literal?

最佳答案

从文档来看,答案似乎是一个相当明确的“否”。
首先,正如您可能知道的(确实可能从名称中猜到),Base.unsafe_convert在这方面不提供安全性,带有 docstring 警告

Be careful to ensure that a Julia reference to x exists as long as the result of this function will be used


仅存在一个指针肯定不会提供这一点。更糟糕的是,作为 Base.cconvert 的文档字符串笔记

Neither convert nor cconvert should take a Julia object and turn it into a Ptr.


将 Julia 对象转换为 Ptr 的推荐方法是什么? ?那似乎是 Base.pointer ,它在其文档中提供了更多有用的信息
help?> Base.pointer
pointer(array [, index])

Get the native address of an array or string, optionally at a given location index.

This function is "unsafe". Be careful to ensure that a Julia reference to array exists
as long as this pointer will be used. The GC.@preserve macro should be used to protect
the array argument from garbage collection within a given block of code.

Calling Ref(array[, index]) is generally preferable to this function as it guarantees
validity.
值得注意的是,返回的指针
julia> s = "some string"
"some string"

julia> Base.pointer(s)
Ptr{UInt8} @0x000000010d4b2838

julia> Base.unsafe_convert(Ptr{UInt8}, s)
Ptr{UInt8} @0x000000010d4b2838

julia> Base.unsafe_convert(Ptr{UInt8}, Base.cconvert(Ptr{UInt8}, s))
Ptr{UInt8} @0x000000010d4b2838
是相同的。
更多有用的信息可以在 Base.GC.@preserve 中找到。文档字符串依次为:
help?> Base.GC.@preserve
GC.@preserve x1 x2 ... xn expr

Mark the objects x1, x2, ... as being in use during the evaluation of the expression
expr. This is only required in unsafe code where expr implicitly uses memory or other
resources owned by one of the xs.

Implicit use of x covers any indirect use of resources logically owned by x which the
compiler cannot see. Some examples:

• Accessing memory of an object directly via a Ptr

• Passing a pointer to x to ccall

• Using resources of x which would be cleaned up in the finalizer.

@preserve should generally not have any performance impact in typical use cases where
it briefly extends object lifetime. In implementation, @preserve has effects such as
protecting dynamically allocated objects from garbage collection.

Examples
≡≡≡≡≡≡≡≡≡≡

When loading from a pointer with unsafe_load, the underlying object is implicitly
used, for example x is implicitly used by unsafe_load(p) in the following:

julia> let
x = Ref{Int}(101)
p = Base.unsafe_convert(Ptr{Int}, x)
GC.@preserve x unsafe_load(p)
end
101

When passing pointers to ccall, the pointed-to object is implicitly used and should be
preserved. (Note however that you should normally just pass x directly to ccall which
counts as an explicit use.)

julia> let
x = "Hello"
p = pointer(x)
Int(GC.@preserve x @ccall strlen(p::Cstring)::Csize_t)
# Preferred alternative
Int(@ccall strlen(x::Cstring)::Csize_t)
end
5
所以,一些带回家的点
  • Base.pointer(s) 返回的指针当且仅当 (a) 存在对该字符串的 Julia 引用 s 时,指向字符串才是安全的稍后在代码中或 (b) 您使用过 Base.GC.@preserve
  • Base.unsafe_convert(Ptr{UInt8}, Base.cconvert(Ptr{UInt8}, s)) 返回的指针似乎与 Base.pointer 返回的指针具有相同的警告。 ,还有一个神秘和不祥的警告的额外好处。
  • 没有迹象表明 Julia 对象的类型(String vs Array vs 等)很重要。
  • 关于julia - Julia 字符串文字的生命周期是多少,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68324542/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com