va_list使用及两个注意项(可能导致崩溃和少1个字符)

两个注意项:

        1、linux平台上vsnprintf会破坏va_list变量,需要重新调用va_start,否则可能访问错位崩溃。

        2、vsnprintf会留一个字节补0结束,但返回值不包含,所以必须判断返回值小于分配的空间。

具体代码分析:

#include
#include

constexpr size_t AUTO_BUF_LEN = 8;

void myPrintf(const char*format, ...)
{
	char buffer[AUTO_BUF_LEN];
	char *pBuf = buffer;
	va_list args;

	va_start(args, format);
	int len = vsnprintf(buffer, AUTO_BUF_LEN, format, args);
	if (len < AUTO_BUF_LEN) // 返回值不包含结束符,必须 <
	{
		printf("%s\n", buffer);
	}
	else
	{
		printf("重新分配空间:%d\n", len);

		// vsnprintf会添加\0结束符,返回值不包含,
		char *buf = new char[len + 1];
		//va_start(args, format); //linux 上必须加这行,vsnprintf会破坏args
		vsnprintf(buf, len + 1, format, args);
		printf("%s\n", buf);
		delete []buf;
	}
	va_end(args);
}

int main()
{
	printf("小于默认空间测试:\n");
	myPrintf("1234567");
	myPrintf("%s", "1234567");
	myPrintf("%s%d", "12345", 67);

	printf("\n等于默认空间测试:\n");
	myPrintf("12345678");
	myPrintf("%s","12345678");
	myPrintf("%s%d", "123456", 78);

	printf("\n大于默认空间测试:\n");
	myPrintf("123456789");
	myPrintf("%s", "123456789");
	myPrintf("%s%d", "1234567", 89);

	getchar();
}

windows运行:

va_list使用及两个注意项(可能导致崩溃和少1个字符)_第1张图片

你可能感兴趣的:(linux)