Пытаюсь написать создание по формату std::string с помощью vsnprintf, но что-то где-то пошло не так и программа падает во время вызова vsnprintf.
inline std::string makeString(const char * pFormat, va_list vaList)
{
int nLength = strlen(pFormat) * 2;
std::unique_ptr<char[]> pFormatted;
while (true)
{
pFormatted.reset(new char[nLength]);
int nFormattedLength;
va_start(vaList, pFormat);
nFormattedLength = vsnprintf(pFormatted.get(), nLength, pFormat, vaList);
va_end(vaList);
if (nFormattedLength < 0 || nFormattedLength >= nLength)
nLength += std::abs(nFormattedLength - nLength + 1);
else
break;
}
return std::string(pFormatted.get());
}
inline std::string makeString(const char * pFormat, ...)
{
va_list vaList;
std::string result;
va_start(vaList, pFormat);
result = makeString(pFormat, vaList);
va_end(vaList);
return std::move(result);
}
int main()
{
std::cout << makeString("testing %d %s %d\n", 58, "ggg", 76) << std::endl;
}
По логике ошибка где-то в перевыделении памяти, поскольку следующий код работает корректно, но где именно - понять не могу
void test(const char * pFormat, ...)
{
va_list vaList;
char arr[1024];
va_start(vaList, pFormat);
vsnprintf(arr, 1024, pFormat, vaList);
va_end(vaList);
printf("%s", arr);
}
int main()
{
test("testing %d %s %d\n", 58, "ggg", 76);
}
Вся идея подхода с передачей va_list в дополнительную функцию заключается в том, что va_start для этого va_list делается именно и только в вызывающей функции, а во внутренней функции его делать не надо - туда приходит уже "стартовавший" va_list.
У вас во второй makeString правильно делается va_start, а затем внутри первой makeString снова делается va_start. Повторный va_start не нужен.
Как развивать веб-проекты в 2026 году: технологии, контент E-E-A-T и факторы доверия
Современные инструменты для криптотрейдинга: как технологии помогают принимать решения
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники