按值传递va_list时访问冲突
Access violation when passing a va_list by value
当Microsoft Visual C++ 2005
按值将 va_list 参数从一个成员函数传递到另一个成员函数时,我收到访问冲突错误(使用 Visual 2005(。如果我通过引用传递它,一切都按预期工作,但va_list不应该通过引用传递,是吗?
class A
{
public:
char * getformatted( char const * a_format, ... )
{
va_list argp;
va_start( argp, a_format );
char * result = getformatted( a_format, argp );
va_end( argp );
return result;
}
char * getformatted( char const * a_format, va_list /*&*/ a_args )
{
static char buffer[ 256 ];
int length = vsprintf( buffer, a_format, a_args ); // Access violation.
return buffer;
}
};
int main( int argc, char * argv[] )
{
char * str = A().getformatted( "foo%s", "bar" );
return 0;
}
在<stdarg.h>
中:
typedef char * va_list
所以A().getformatted( "foo%s", "bar" )
由于字符串文字衰减到 C 兼容性而char *
而调用A::getformatted( char const * a_format, va_list /*&*/ a_args)
。
如果逐步执行,是否按预期顺序调用两个函数?
显示的两个函数具有相似的签名,因此首先检查是确保调用正确发生。这一点尤其重要,因为va_list
通常是char *
的typedef,所以getformatted("foo%s", "bar")
很可能在不先调用getformatted(const char *, ...)
的情况下被调用。
如果是这种情况,并且vsprintf
在任何时候都使用va_next
,则行为将是未定义的。一些编译器将va_
函数作为简单的宏处理,而其他编译器则具有重要的函数。
通常为了解决这个问题,带有va_list
的函数将以v
(vsprintf
等人(为前缀,以消除任何潜在的歧义。
在最好的情况下,由于您使用的是C++,因此通常最好使用std::stringstream
或boost::format
。两者都会给你类型安全,并防止大多数这样的情况,而后者保留了printf
的大部分语法。
相关文章:
- 写入位置0x0000000C时发生访问冲突
- 引发异常:读取访问冲突**dynamicArray**为0x1118235.发生
- 链表中写入访问冲突的未知原因
- C++中的openCV Mat访问冲突
- C++尝试深度复制唯一指针时出现内存访问冲突
- C++ 中动态二维数组的访问冲突
- 从嵌套循环中的 std::list 中删除将返回访问冲突
- 写入访问冲突异常
- 在类 12.exe 中0x7B37FF80 (ucrtbased.dll) 引发异常: 0xC0000005:访问冲突读
- 0xC0000005:访问冲突写入位置0xCDCDCDCD动态分配错误
- 读取访问冲突.这0xCDCDCDCD
- 0xC0000005:访问冲突读取位置 0x00000000. 重载 == 运算符的问题
- 插入数组时违反写访问冲突
- 使用 ReadProcessMemory 获取字符串值的访问冲突
- 尝试通过共享指针使用变量时读取访问冲突
- 堆栈上的 C++ 访问冲突写入异常
- 引发异常:写访问冲突. temp 为 nullptr
- 将静态字符数组中的字符分配给动态分配的字符数组 - 访问冲突
- 在C++中删除双向链表的头节点后出现访问冲突异常
- 在c++中对STL List使用push_back()会导致访问冲突,崩溃