У меня есть void *
, назовите его data
, длина которого я знаю, но не завершена нулем. Я звоню вот так snprintf(line, sizeof(line), "%*s", n, (const char*)data)
, где n
- известная длина. Почти всегда это работает, но иногда это приводит к segfault.
Всякий раз, когда происходит segfault, обратный след говорит, что проблема внутри 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 символов, но не завершен нулем, на самом деле, кажется, что он лежит прямо против сегмента. Я предполагаю, что 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 по привычке.