If anyone is using the toCStringArray function ( <...
# kotlin-native
n
If anyone is using the toCStringArray function ( https://kotlinlang.org/api/latest/jvm/stdlib/kotlinx.cinterop/to-c-string-array.html ) then they need to be aware that it produces a C Array which isn't null terminated when Kotlin Native's experimental memory model is used. However if Kotlin Native's old memory model is used then a null terminated C Array is produced.
🐞 2
e
I don't think it's documented to be null terminated, and the function itself is the same in either memory model. it is possibly just an accident of padding in the old memory model
if you need a null terminator, you should be able to add one explicitly
Copy code
memScoped {
    allocArrayOf(strings.map { it.cstr.getPointer(this) } + null)
}
👍 1
n
@Pavel Kunyavskiy [JB] - How is the
toCStringArray
function supposed to behave (aka what should be happening "under the hood")?
I have developed an extension function to get around the issue:
Copy code
fun Array<String>.toCArray(): CArrayPointer<CPointerVar<ByteVar>> = memScoped {
    val result = allocArray<CPointerVar<ByteVar>>(size + 1)
    @Suppress("ReplaceRangeToWithUntil")
    (0..(size - 1)).forEach { result[it] = this@toCArray[it].cstr.getPointer(this) }
    result[size] = null
    result
}
e
returning
result
there is really not what you should be doing - that's dangling memory
👍 1
https://kotlinlang.org/api/latest/jvm/stdlib/kotlinx.cinterop/mem-scoped.html "Runs given block providing allocation of memory which will be automatically disposed at the end of this scope."
p
I don't see any reasons neither in code, nor in docs, why it should add null. Being null-terminated is specific to some linux APIs, a lot of other APIs use other ways to manage c-arrays size. I'm a bit confused with fact, this function in defined on Array<String>, but not Array<String>. So I don't see any easy ways to add this null using this function, but it can be done with direct usage of autofreeScope.allocArrayOf. Btw, if you don't like until operator, consider using result.indices for this range.