I met a strange problem whne tying to convert a Lua string to C char arry.
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)
run this code get:
[root@origin ~]# luajit test.lua
16
1234567890abcdef
Segmentation fault
I know ffi.new("unsigned char[?]", #str+1, str)
will solve this, but I dont know why.
I don't think it is the \0
problem because I found some strange point.
str
is not 16 bytes, this will not happen.ffi.cdef
which I didn't use , this will not happen.if I put ffi.cdef
behind the ffi.new
,this will not happen .
[root@origin ~]# luajit test.lua
17
1234567890abcdefg
// this is the result that I only append a 'g' to `str`.
I tried on Luajit 2.0.5 and Luajit 2.1.0-beta3 with default compiler arguments.
So, is there anyone knows how this happen, thanks.
It is exactly because of string size is 17 but array allocated only for 16 bytes. https://github.com/LuaJIT/LuaJIT/blob/0c0e7b168ea147866835954267c151ef789f64fb/src/lj_cconv.c#L582 is the code that copies string to resulting array. As you can see, if target is array and its size is smaller than string length, it shrinks string; however your type is VLA (variable-length array), and for VLA size is not specified (it is 2**32-1
, actually, which is way bigger than 17).
"I don't get error if" is not an argument here - you stomp memory that is used for something else. Sometimes stomping extra byte with 0 is not fatal (e.g. due to alignment this byte wasn't used anyway, or just happened to be 0 already) or doesn't result in hard crash - it doesn't make it correct.