gpt4 book ai didi

c - 如果保存副本并将其提供给另一个线程,为什么 va_list var-arg 副本无法按预期工作?

转载 作者:太空宇宙 更新时间:2023-11-04 07:57:26 25 4
gpt4 key购买 nike

如本例所示,如果我直接从 main 调用 tsub,则输出符合预期。如果为 tsub 启用 pthread 模式,这不会给出预期的输出。

va_list vobj;

void *tsub (void *arg)
{
printf ("vobj: %d, %f\n", va_arg (vobj, int), va_arg (vobj, double));
return NULL;
}

void print_mydb (char *name, ...)
{
va_list ap;
va_start (ap, name);
va_copy (vobj, ap);
va_end (ap);
}

int main (void)
{
pthread_t tid;
print_mydb ("b10", 6, 5.23);

#if 1
printf ("THREADY!!!!!\n");
pthread_create (&tid, NULL, tsub, (void *)vobj);
pthread_join (tid, NULL);

#else
tsub (NULL);

#endif
return 0;
}

直接 tsub 调用的输出:

vobj: 6, 5.230000

tsub 的 pthread 调用输出:

THREADY!!!!!
vobj: 0, 0.000000

最佳答案

AFAICS ,你两次都在调用未定义的行为;它有时有效(似乎在这种情况下有效)有时无效。当 print_mydb() 返回时,复制的 vobj 指向无效数据 — 提供它指向的数据(参数列表)的函数调用已返回,因此内容vobj 现在没有意义了。无论您是直接调用 tsub() 还是通过 pthread_create() 调用都没有关系,一旦传递给 print_mydb(),您就是在滥用内存.当 pthread_create() 在调用时践踏内存时,情况会更糟。

此外,调用 va_copy() 的函数 必须 在返回之前对复制的列表调用 va_end()C11 §7.16.1 Variable argument list access macros ¶1

Each invocation of the va_start and va_copy macros shall be matched by a corresponding invocation of the va_end macro in the same function.

因此,print_mydb() 表现出未定义的行为,因为它在返回之前没有在 vobj 上调用 va_end()

关于c - 如果保存副本并将其提供给另一个线程,为什么 va_list var-arg 副本无法按预期工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49043288/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com