C 中的可变参数函数

发布于 2024-12-09 15:36:19 字数 865 浏览 1 评论 0原文

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 memory\n"); /* 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 %s\n", pinfile);

    return 0;
}

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(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 %s\n", pinfile);

    return 0;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

哥,最终变帅啦 2024-12-16 15:36:19

/* test 1 */ 下的代码不会打印任何内容,因为 vsnprint() 函数不会打印到 stdout;它只是将其输出写入提供的缓冲区。

不过,如果代码没有崩溃那就纯属运气了,因为这一行:

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

实际上告诉 calloc() 分配 0 字节的内存。因此,我认为不能保证 logbuf 指向的内存也归零——因此,您的缓冲区不仅为零字节长,而且调用 strlen() 它可能会崩溃或给你一个无效的结果。

另外,vsnprint() 的第二个参数应该是缓冲区的大小,即您为 logbuf 分配的大小,而不是任何字符串的长度已经在其中了;这是为了限制写入缓冲区的字节数,以避免缓冲区溢出。

因此,为了让一切正常工作,您需要更改:

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

..to

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

....为 1 项 LOGBUFFERSIZE 字节分配空间。并且还要更改:

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

..to..

vsnprintf(logbuf, LOGBUFFERSIZE, fmt, va);

..将缓冲区的大小传递给它并删除无用的 (void) 强制转换。并且还要在其后面添加一行打印logbuf,如:

fputs(logbuf, stderr);

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.

土豪 2024-12-16 15:36:19

这:

vsnprintf(logbuf, strlen(logbuf)...

永远不会格式化任何内容,因为 logbuf 全部为零(已由 calloc 分配,因此 strlen 将返回零,这使得 vsnprintf永远不要格式化任何东西,因为你告诉它最多打印零个字符。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文