我遇到了一个奇怪的问题,即将Lua字符串转换为C char arry。
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<div id="myDiv"></div>
运行此代码获取:
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
不是16字节,则不会发生这种情况。str
,则不会发生这种情况。如果我将ffi.cdef
置于ffi.cdef
后面,则不会发生这种情况。
ffi.new
我尝试使用默认编译器参数的Luajit 2.0.5和Luajit 2.1.0-beta3。
那么,有没有人知道这是怎么发生的,谢谢。
答案 0 :(得分:1)
正是因为字符串大小为17,而且数组仅分配了16个字节。 https://github.com/LuaJIT/LuaJIT/blob/0c0e7b168ea147866835954267c151ef789f64fb/src/lj_cconv.c#L582是将字符串复制到结果数组的代码。如您所见,如果target是数组且其大小小于字符串长度,则会收缩字符串;但是你的类型是VLA(可变长度数组),并且没有指定VLA大小(实际上是2**32-1
,这大于17)。
“我不会得到错误,如果”这里不是一个参数 - 你踩踏用于其他东西的内存。有时用0来重写额外字节并不是致命的(例如由于对齐此字节无论如何都没有使用,或者恰好已经是0)或者不会导致硬崩溃 - 它不能使其正确。