You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 18:35:23