1)为什么/* test1 */
块下的代码打印不出任何东西,而/* test2 */
块下的代码打印正确?
2)如何在/* test 1 */
代码块中使用va_arg(va, char*)
。
void rdfDBG(int dbglevel, const char *fmt, ...) {
va_list va;
#if 1 /* test 1 */
char* logbuf;
if ((logbuf = calloc(0x0, LOGBUFFERSIZE))== NULL)
fprintf(stderr, "out of memoryn"); /* 1. Is there a better way instead of using fprintf? */
va_start(va, fmt);
(void) vsnprintf(logbuf, strlen(logbuf), fmt, va); /* 2. print nothing */
va_end(va);
free(logbuf);
#endif
#if 0 /* test 2 */
va_start(va, fmt);
vprintf(fmt, va); /* 2. print "pinfile pings6.txt" */
va_end(va);
#endif
}
int ptInitialize(){
char* pinfile;
pinfile = "pings6.txt";
rdfDBG(kINFO, "pinfile %sn", pinfile);
return 0;
}
/* test 1 */
下的代码不打印任何东西,因为vsnprint()
函数不打印到stdout;它只是将输出写入所提供的缓冲区。
如果代码没有崩溃纯属运气,因为:
if ((logbuf = calloc(0x0, LOGBUFFERSIZE))== NULL)
实际上告诉calloc()
分配0字节的内存。正因为如此,我认为不能保证logbuf
所指向的内存也为零——所以不仅你的缓冲区长为零字节,而且在它上调用strlen()
可能会崩溃或给你一个无效的结果。
另外,vsnprint()
的第二个参数应该是缓冲区的大小,这是你为logbuf
分配的大小,而不是已经在其中的任何字符串的长度;这是为了限制写入缓冲区的字节数,以避免缓冲区溢出。
因此,要使一切正常工作,您需要更改:
if ((logbuf = calloc(0x0, LOGBUFFERSIZE))== NULL)
. . . .
if ((logbuf = calloc(1, LOGBUFFERSIZE))== NULL)
. .为1项LOGBUFFERSIZE
字节分配空间。并更改:
(void) vsnprintf(logbuf, strlen(logbuf), fmt, va);
. ., . .
vsnprintf(logbuf, LOGBUFFERSIZE, fmt, va);
. .将缓冲区的大小传递给它,并删除无用的(void)
强制转换。并添加一行来打印logbuf
,例如:
fputs(logbuf, stderr);
。
This:
vsnprintf(logbuf, strlen(logbuf)...
将永远不会格式化任何内容,因为logbuf
都是零(已经由calloc
分配,因此strlen
将返回零,这使得vsnprintf永远不会格式化任何内容,因为您告诉它最多打印0个字符。