linux list 添加失败,c – Linux上的va_list错误行为

我有一些代码将variadic参数转换为va_list,然后将列表传递给一个函数,然后调用vsnprintf.这在

Windows和OS X上运行良好,但在

Linux上却出现了奇怪的结果.

在以下代码示例中:

#include

#include

#include

#include

char *myPrintfInner(const char *message, va_list params)

{

va_list *original = &params;

size_t length = vsnprintf(NULL, 0, message, *original);

char *final = (char *) malloc((length + 1) * sizeof(char));

int result = vsnprintf(final, length + 1, message, params);

printf("vsnprintf result: %d\r\n", result);

printf("%s\r\n", final);

return final;

}

char *myPrintf(const char *message, ...)

{

va_list va_args;

va_start(va_args, message);

size_t length = vsnprintf(NULL, 0, message, va_args);

char *final = (char *) malloc((length + 1) * sizeof(char));

int result = vsnprintf(final, length + 1, message, va_args);

printf("vsnprintf result: %d\r\n", result);

printf("%s\r\n", final);

va_end(va_args);

return final;

}

int main(int argc, char **argv)

{

char *test = myPrintf("This is a %s.", "test");

char *actual = "This is a test.";

int result = strcmp(test, actual);

if (result != 0)

{

printf("%d: Test failure!\r\n", result);

}

else

{

printf("Test succeeded.\r\n");

}

return 0;

}

第二个vsnprintf调用的输出为17,strcmp的结果为31;但我不明白为什么vsnprintf会回来17看到这是一个测试.是15个字符,添加NULL,你得到16.

我见过的相关主题,但没有解决这个话题:

使用@Mat的答案(我正在重用va_list对象,这是不允许的),这正是我链接到的第一个相关线程.所以我尝试了这个代码:

char *myPrintfInner(const char *message, va_list params)

{

va_list *original = &params;

size_t length = vsnprintf(NULL, 0, message, params);

char *final = (char *) malloc((length + 1) * sizeof(char));

int result = vsnprintf(final, length + 1, message, *original);

printf("vsnprintf result: %d\r\n", result);

printf("%s\r\n", final);

return final;

}

其中,per the C99 spec(第7.15节中的脚注)应该有效:

It is permitted to create a pointer to a va_list and pass that pointer

to another function, in which case the original function may make

further use of the original list after the other function returns.

但我的编译器(C99模式下的gcc 4.4.5)给出了关于myPrintfInner第一行的错误:

test.c: In function ‘myPrintfInner’:

test.c:8: warning: initialization from incompatible pointer type

并且得到的二进制产生与第一次完全相同的效果.

建议的解决方法(不保证可行,但在实践中确实)是首先使用arg_copy:

char *myPrintfInner(const char *message, va_list params)

{

va_list args_copy;

va_copy(args_copy, params);

size_t length = vsnprintf(NULL, 0, message, params);

char *final = (char *) malloc((length + 1) * sizeof(char));

int result = vsnprintf(final, length + 1, message, args_copy);

printf("vsnprintf result: %d\r\n", result);

printf("%s\r\n", final);

return final;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值