# Segfault calling C function, any advice?

**URL:** <https://discourse.julialang.org/t/segfault-calling-c-function-any-advice/94730>\
**Category:** General Usage\
**Tags:** segfault\
**Created:** [February 16, 2023, 4:35pm UTC](https://discourse.julialang.org/t/segfault-calling-c-function-any-advice/94730 "2023-02-16T16:35:07Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![CodeGodz](https://avatars.discourse-cdn.com/v4/letter/c/aeb1de/32.png) [@CodeGodz](https://discourse.julialang.org/u/CodeGodz)\
**Post date:** [February 16, 2023, 4:35pm UTC](https://discourse.julialang.org/t/segfault-calling-c-function-any-advice/94730/1 "2023-02-16T16:35:07Z")

</div>

Hey all,

I’m trying to call the `libsais_int` function from [libsais](https://github.com/IlyaGrebnov/libsais), with signature:  
`int32_t libsais_int(int32_t * T, int32_t * SA, int32_t n, int32_t k, int32_t fs);`

I wrote the following (and also tried using `pointer()` but I cannot seem to get it to work:

```julia
const LIBSAIS = "libsais.so.2"
function create_suffix_array(in_vector::Vector{Int32}, free_space::Int)
    out_vector = zeros(Int32, length(in_vector) + free_space)
    n = length(in_vector)
    k = length(Set(in_vector))
    res = ccall((:libsais_int,LIBSAIS), Cint, (Ref{Vector{Int32}}, Ref{Vector{Int32}}, Cint, Cint, Cint), in_vector, out_vector, n, k, free_space) 
    return out_vector
end
println(create_suffix_array(Int32[2,1,1,1,10], 10000)) 

```

This will: `signal (11): Segmentation fault`

Any tips 🙂

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [February 16, 2023, 5:26pm UTC](https://discourse.julialang.org/t/segfault-calling-c-function-any-advice/94730/2 "2023-02-16T17:26:40Z")

</div>

You probably need to `GC.@preserve in_vector`. Otherwise it can get freed by the garbage collector.

---

<div class="post-metadata">

**Author:** ![CodeGodz](https://avatars.discourse-cdn.com/v4/letter/c/aeb1de/32.png) [@CodeGodz](https://discourse.julialang.org/u/CodeGodz)\
**Post date:** [February 16, 2023, 5:27pm UTC](https://discourse.julialang.org/t/segfault-calling-c-function-any-advice/94730/3 "2023-02-16T17:27:57Z")

</div>

I tried this before:

```julia
function create_suffix_array(in_vector::Vector{Int32}, free_space::Int)
    out_vector = zeros(Int32, length(in_vector) + free_space)
        GC.@preserve in_vector out_vector begin
        n = length(in_vector)
        k = length(Set(in_vector))
        res = ccall((:libsais_int,LIBSAIS), Cint, (Ref{Vector{Int32}}, Ref{Vector{Int32}}, Cint, Cint, Cint), Ref(in_vector), Ref(out_vector), n, k, free_space) 
    end
    return out_vector
end

```

That also segfaults, or should I put the GC preserve there in a different way?

---

<div class="post-metadata">

**Author:** ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)\
**Post date:** [February 16, 2023, 6:34pm UTC](https://discourse.julialang.org/t/segfault-calling-c-function-any-advice/94730/4 "2023-02-16T18:34:44Z")

</div>

Try

```julia
@ccall LIBSAIS.libsais_int(in_vector::Ptr{Int32}, out_vector::Ptr{Int32}, n::Int32, k::Int32, free_space::Int32)::Int32

```

---

<div class="post-metadata">

**Author:** ![CodeGodz](https://avatars.discourse-cdn.com/v4/letter/c/aeb1de/32.png) [@CodeGodz](https://discourse.julialang.org/u/CodeGodz)\
**Post date:** [February 16, 2023, 6:41pm UTC](https://discourse.julialang.org/t/segfault-calling-c-function-any-advice/94730/5 "2023-02-16T18:41:43Z")

</div>

That seems to work, I do get a segfault with other input data but maybe that relates to the the library (altho it should be possible it says in the docs):

```julia
const LIBSAIS = "/home/rickb/tools/suffix/libsais/libsais.so.2"
function create_suffix_array(in_vector::Vector{Int32}, free_space::Int)
    out_vector = zeros(Int32, length(in_vector) + free_space)
    n = length(in_vector)
    k = length(Set(in_vector))
    @ccall LIBSAIS.libsais_int(in_vector::Ptr{Int32}, out_vector::Ptr{Int32}, n::Int32, k::Int32, free_space::Int32)::Int32
    return out_vector
end

println(create_suffix_array(Int32[2,1,1,1,1458521], 10)) # works
println(create_suffix_array(Int32[2,1,1,1,1458521], 1000)) # segfaults

```

> ```
> * @param fs Extra space available at the end of SA array (can be 0, but 4k or better 6k is recommended for optimal performance).
> 
> ```

You think it’s related to the Julia call?

---

<div class="post-metadata">

**Author:** ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)\
**Post date:** [February 16, 2023, 6:44pm UTC](https://discourse.julialang.org/t/segfault-calling-c-function-any-advice/94730/6 "2023-02-16T18:44:00Z")

</div>

Hard to tell. You can try with an equivalent C code and see if that works. When it doesn’t crash, do you get the results you’d expect?

---

<div class="post-metadata">

**Author:** ![CodeGodz](https://avatars.discourse-cdn.com/v4/letter/c/aeb1de/32.png) [@CodeGodz](https://discourse.julialang.org/u/CodeGodz)\
**Post date:** [February 16, 2023, 6:45pm UTC](https://discourse.julialang.org/t/segfault-calling-c-function-any-advice/94730/7 "2023-02-16T18:45:21Z")

</div>

Yeah, the call seems fine now (the first result is what I expect thanks!), but now the second confuses me haha. Lets see if I can code C haha

---

<div class="post-metadata">

**Author:** ![Dan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dan/32/42581_2.png) [@Dan](https://discourse.julialang.org/u/Dan)\
**Post date:** [February 16, 2023, 11:34pm UTC](https://discourse.julialang.org/t/segfault-calling-c-function-any-advice/94730/8 "2023-02-16T23:34:06Z")

</div>

> [@CodeGodz](#):
>
> `k = length(Set(in_vector))`

I think it should be:

```julia
k = maximum(in_vector)+1

```

As the parameter is the alphabet size (which includes missing letters). So essentially, the maximum value in the input array.  
Specifically, if input is `[1,5,2,2]` is should be at least `5+1` = `6` and not `3` which is the `length(Set([1,5,2,2]))`. The `+1` on the maximum is because `0` is a an alphabet value too.

As, the maximum value in the example is rather big, it might be productive to first reduce the maximum alphabet value with a lookup table as follows:

```julia
v = Int32[2,1,1,1,1458521]
d = Dict(Iterators.map(reverse,pairs(sort(unique(v)))))
newv = Int32.(get.(Ref(d), v, 0))

```

Now, the `maximum(newv)+1` should be minimal for the input vector, and ready to be shipped to `libsais_int`. Since the ordering of inputs are preserved, the output suffix array is also identical.
