【问题标题】:How do you manipulate a void pointer passed as a parameter in a variadic function in C如何在 C 中的可变参数函数中操作作为参数传递的 void 指针
【发布时间】:2021-02-25 03:13:45
【问题描述】:

我有以下可变参数函数(vsprintf 的一个版本):

buf[size] = '0'; size++;                
buf[size] = 'x'; size++;
void **ptr = va_arg(arg, void *);
num = unsigned_to_base(&buf[size], bufsize, (int)*ptr, HEX_BASE, 8);

函数unsigned_to_base() 接收一个十六进制数字并将其作为字符串放在buf 中(0x 前缀必须手动放置,因为函数不会自动。 unsigned_to_base 作用如下:

int unsigned_to_base(char *buf, size_t bufsize, unsigned int val, int base, int min_width) 其中buf 是目的地,bufsizebuf 的大小,val 是有问题的值,base 是表示字符串的基数系统(在这种情况下它是基数 16, hex),min_width 是输出字符串的最小宽度,如果需要,用前导 0 填充前面。该函数返回写入buf的字符数。

我在可变参数函数中提取的参数是(void *) 0x20200004,我试图返回"0x20200004"。但是,我收到的实际返回值是"0x00012000"。我做错了什么?

谢谢!

【问题讨论】:

  • 顺便说一句,使用-fsanitize=address 编译会使程序崩溃,并准确告诉我哪一行出错,以及发生了什么(取消引用 0x20200004)。这是一个很棒的工具,只需要一个额外的调试标志即可使用。

标签: c pointers printf variadic-functions


【解决方案1】:

va_arg 返回作为参数给出的类型的值。您的va_arg 返回void*,但您将其存储在void** 中,我认为这不是您想要的。另外,我看到你有 C++ 标签,那你为什么还要在 C++ 中使用可变参数列表呢?

【讨论】:

    【解决方案2】:

    当您调用 unsigned_to_base 时,您会取消引用 ptr,这会为您提供地址 0x20200004 处的值。相反,您需要值 0x20200004,所以不要取消引用:

    num = unsigned_to_base(&buf[size], bufsize, (int)ptr, HEX_BASE, 8);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-20
      • 2019-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多