开发者

variadic function in C

开发者 https://www.devze.com 2023-04-12 18:12 出处:网络
1) Why code under /* test1 */ chunk do not print out anything, but code under /* test2 */ print correctly?

1) Why code under /* test1 */ chunk do not print out anything, but code under /* test2 */ print correctly?

2) How to use va_arg(va, char*) in /* test 1 */ code chunk.


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 memory\n"); /* 1. Is there a better way instead of using fprintf? */

    va_start(va, fmt);
    (void) vsnprintf(log开发者_运维技巧buf, 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 %s\n", pinfile);

    return 0;
}


The code under /* test 1 */ doesn't print anything because the vsnprint() function doesn't print to stdout; it just writes its output into the provided buffer.

It's pure luck if the code didn't crash, though, because the line:

if ((logbuf = calloc(0x0, LOGBUFFERSIZE))== NULL)

actually tells calloc() to allocate 0 bytes of memory. Because of this, I don't think it's guaranteed that the memory logbuf points at is zeroed either -- so not only is your buffer zero bytes long, but calling strlen() on it could crash or give you an invalid result.

Also, the second argument to vsnprint() is supposed to be the size of the buffer, that is the size you've allocated for logbuf, not the length of any string already in it; it's to limit the number of bytes written to the buffer to avoid a buffer overrun.

So to get everything working, you need to change:

    if ((logbuf = calloc(0x0, LOGBUFFERSIZE))== NULL)

..to..

    if ((logbuf = calloc(1, LOGBUFFERSIZE))== NULL)

..to allocate space for 1 item of LOGBUFFERSIZE bytes. And also change:

(void) vsnprintf(logbuf, strlen(logbuf), fmt, va);

..to..

vsnprintf(logbuf, LOGBUFFERSIZE, fmt, va);

..to pass it the size of your buffer and remove the useless (void) cast. And also add a line to print logbuf, such as:

fputs(logbuf, stderr);

after it.


This:

vsnprintf(logbuf, strlen(logbuf)...

Will never format anything, because logbuf is all zeros (having been allocated by calloc, and so strlen will return zero, which makes vsnprintf never format anything because you told it to print at most zero characters.

0

精彩评论

暂无评论...
验证码 换一张
取 消