我有一个void *,叫它data,我知道它的长度,但不是空终止的。我这样打电话,已知长度snprintf(line, sizeof(line), "%*s", n, (const char*)data)在哪里。n几乎总是这样,但偶尔会导致段错误。
每当发生段错误时,回溯表明问题出在 strlen 内部。当我data在 gdb 中打印时,我看到类似这样的内容
(gdb) p n
$1 = 88
(gdb) p (const char*) data
$2 = 0x1d752fa8
"JASDF" ... "ADS"<Address 0x1d753000 out of bounds>
(gdb) p 0x1d753000-0x1d752fa8
$3 = 88
data确实是 88 个字符,但不是以 null 结尾的,事实上,它似乎正好靠在一个段上。我的猜测是 snprintf 在数据上总是被称为 strlen ,我通常很幸运,即使data不是空终止,\0在我点击该段之前有一个,然后偶尔我会不走运,它是。是对的吗?如果是这样,解决方法是什么?
这就是堆栈跟踪的样子
#0 0x0000003c8927839e in strlen () from /lib64/libc.so.6
#1 0x0000003c89246749 in vfprintf () from /lib64/libc.so.6
#2 0x0000003c8926941a in vsnprintf () from /lib64/libc.so.6
#3 0x0000003c8924d0a3 in snprintf () from /lib64/libc.so.6
编辑要回答我自己关于变通的问题,strncpy 是一个更合适的调用函数。我习惯使用 snprintf。