作者热门文章
- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有一个 void *
,称它为 data
,我知道它的长度,但它不是 null 终止的。我这样调用 snprintf(line, sizeof(line), "%*s", n, (const char*)data)
其中 n
是已知长度.这几乎总是有效,但偶尔会导致段错误。
每当发生段错误时,回溯都会说问题出在 strlen 内部。当我在 gdb 中打印 data
时,我看到类似这样的内容
(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
segmentation ,然后偶尔我会倒霉,确实如此。是对的吗?如果是这样,解决方法是什么?
这是堆栈跟踪的样子
#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。
最佳答案
snprintf(line, sizeof(line), "%*s", n, (const char*)data)
data
不是零终止的吗?那你就错了。
snprintf(line, sizeof(line), "%.*s", n, (const char*)data);
注意点。
在字符串的情况下,*.*
中的第一个 *
如果所需的输出(屏幕上)长度 - 输入长度是第二个 *
。 man printf
了解更多。
很明显,在 %*s
的情况下,格式化可能会调用 strlen(),因为它需要知道是否需要填充输出以及如何填充它。
关于c - snprintf 中的 strlen 调用是否导致此段错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3153855/
我是一名优秀的程序员,十分优秀!