使用ffi将lua字符串转换为C字符串时出现分段错误

使用ffi将lua字符串转换为C字符串时出现分段错误,lua,ffi,luajit,Lua,Ffi,Luajit,我在将Lua字符串转换为C字符时遇到了一个奇怪的问题 local str = "1234567890abcdef" local ffi = require "ffi" ffi.cdef[[ int printf(const char *fmt, ...); ]] print(#str) print(str) local cstr = ffi.new("unsigned char[?]", #str, str) 运行以下代码获取: [root@origin ~]# luajit test

我在将Lua字符串转换为C字符时遇到了一个奇怪的问题

local str = "1234567890abcdef"
local ffi = require "ffi"
ffi.cdef[[
    int printf(const char *fmt, ...);
]]
print(#str)
print(str)
local cstr = ffi.new("unsigned char[?]", #str, str)
运行以下代码获取:

[root@origin ~]# luajit test.lua 
16
1234567890abcdef
Segmentation fault
我知道
ffi.new(“unsigned char[?]”,#str+1,str)
会解决这个问题,但我不知道为什么

我不认为这是
\0
问题,因为我发现了一些奇怪的地方

  • 如果
    str
    不是16字节,则不会发生这种情况
  • 如果我删除了未使用的
    ffi.cdef
    ,则不会发生这种情况
  • 如果我将
    ffi.cdef
    放在
    ffi.new
    后面,则不会发生这种情况

    [root@origin ~]# luajit test.lua
    17
    1234567890abcdefg
    // this is the result that I only append a 'g' to `str`.
    
我使用默认编译器参数在Luajit 2.0.5和Luajit 2.1.0-beta3上进行了尝试


所以,有没有人知道这是怎么发生的,谢谢。

这正是因为字符串大小是17,但数组只分配了16字节。将字符串复制到结果数组的代码。如您所见,若目标是数组且其大小小于字符串长度,则会收缩字符串;但是,您的类型是VLA(可变长度数组),并且没有指定VLA大小(实际上是
2**32-1
,比17大得多)


“Idon't get error if”不是这里的一个参数——你踩下了用来做其他事情的内存。有时,用0跺额外字节不是致命的(例如,由于对齐,该字节没有被使用,或者恰好已经是0),或者不会导致硬崩溃-这并不正确。

此问题是由于缺少终止零的位置。你必须使用
#str+1
@EgorSkriptunoff我不这么认为,你能解释一下为什么它只发生在转换一个16字节的字符串时吗?