Julia中实现释放Cstring并置空指针的函数求助
在Julia中实现释放Cstring内存并置空指针的函数
我用Julia编写了一个生成合法Cstring的函数,该Cstring存储在由malloc分配的内存中,使用后需要释放内存。我需要一个Julia函数,接收Cstring或其指针/引用,调用C的free释放内存,并将等效的char*置空。仅释放内存的函数容易编写,但难点在于将Cstring指针置空。在C中这类函数接收char**类型参数,执行free(*mem_p_p); *mem_p_p = NULL,但我在Julia中无法找到获取等效char**的方法,查阅官方文档仍无法解决。以下是我的多次失败尝试:
Edit 1: 首次失败尝试代码
function free_cstring_null!(c_string_p::Ptr{Cstring})::Nothing println("free_cstring_null!(): Started.") println("free_cstring_null!(): c_string_p ", c_string_p) c_string = unsafe_load(c_string_p) println("free_cstring_null!(): c_string ", c_string) @ccall printf("free_cstring_null!(): Calling from C: %s\n"::Ptr{UInt8}, c_string::Cstring)::Cint; Base.unsafe_store!(c_string_p, C_NULL) # *c_string_p = NULL return nothing end
Edit 2: 简化为Float64内存管理的尝试
我尝试简化问题,仅对单个Float64进行内存管理,但同样无法实现,因为Julia似乎不支持获取对应指针。该实验的目标是创建可被C调用的Julia函数,释放malloc分配的内存并将指针置空,以避免重复释放风险。代码如下:
Base.@ccallable function free_and_null_float!(mem_p_p::Ptr{Ptr{Float64}})::Nothing println("free_and_null_float!(...): mem_p_p ", mem_p_p, " ### typeof(mem_p_p) ", typeof(mem_p_p)) mem_p = unsafe_load(mem_p_p) println("free_and_null_float!(...): mem_p ", mem_p, " ### typeof(mem_p) ", typeof(mem_p)) @ccall free(mem_p::Ptr{Cchar})::Cvoid mem_p = C_NULL return nothing end function double_memory()::Nothing myDouble::Float64 = 666.666 # 创建一个测试用的Float64变量 mem_p::Ptr{Float64} = @ccall malloc(8::Int)::Ptr{Float64} # 分配内存用来存储Float64 unsafe_store!(mem_p, myDouble) # 将Float64写入分配的内存 myDoubleFromMalloc::Float64 = unsafe_load(mem_p) # 从内存中读取Float64 println("myDoubleFromMalloc ", myDoubleFromMalloc) # 打印读取到的Float64值 arg = pointer(mem_p) # 这里同样无法正常工作 free_and_null_float!(arg) return nothing end
Edit 3: 回到字符串场景的尝试
回到字符串场景,相关代码如下:
my_Cstring::Cstring = Cstring(mem_p) println("my_Cstring ", my_Cstring, " ### typeof(my_Cstring) ", typeof(my_Cstring)) arg = Ptr{Cstring}(pointer(my_Cstring)) # 这行代码不报错,但只是做了类型转换,并没有返回变量my_Cstring的地址,而是直接返回my_Cstring本身;因为Cstring本质就是个指针 println("arg ", arg, " ### typeof(arg) ", typeof(arg)) free_and_null_string!(arg) println("After free_and_null(...), mem_p is ", mem_p) println("After free_and_null(...), arg is ", arg) @ccall printf("Reading from the copy is dereferencing... '%s'\n"::Ptr{Cchar}, mem_p::Ptr{Cchar})::Cvoid
对应的释放函数是问题核心:
Base.@ccallable function free_and_null_string!(mem_p_p::Ptr{Cstring})::Cvoid println("free_and_null!(...): mem_p_p ", mem_p_p, " ### typeof(mem_p_p) ", typeof(mem_p_p)) mem_p::Ptr{Cchar} = unsafe_load(mem_p_p) println("free_and_null!(...): mem_p ", mem_p, " ### typeof(mem_p) ", typeof(mem_p)) # @ccall free(mem_p::Ptr{Cchar})::Cvoid if false unsafe_store!(mem_p_p, C_NULL) # 这行本该像C里那样修改调用方的参数,但因为pointer(Cstring)返回的是Cstring本身,所以实际上只是把分配内存的第一个字符设为0了。把false改成true就能看到调用方printf的输出变化 else unsafe_store!(mem_p_p + 10, C_NULL) end return nothing end
内容的提问来源于stack exchange,提问作者TradingDerivatives.eu
相关产品推荐
相关产品推荐

