C语言中的可变函数



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个字符。

相关内容

  • 没有找到相关文章

最新更新