字符串格式化函数引起的崩溃

一. 问题描述

我们常用的格式化字符串函数有:

HRESULT StringCchVPrintf(_Out_ LPTSTR  pszDest,_In_  size_t  cchDest,_In_  LPCTSTR pszFormat,_In_  va_list argList
);
int printf ( const char * format, ... );

对于如下的调用:

char buf[100] = {0};
StringCchVPrintf(buf, 100, "select * from member where name like '%sjj%';");

我们在buf中并不能得到想要的select * from member where name like '%sjj%';字符串,不出意外,%sjj%处的%s会变成乱码。因为函数将%sjj%中的%s当做了字符串格式化串了,而我们又没有给最后一个参数(即可变参数)传值,根据可变参数的原理,默认会根据format参数的地址来取一个地址让%s进行输出。具体计算方式参考va_start宏定义:

#define va_start _crt_va_start
#define _crt_va_start(ap,v)  ( ap = (va_list)_ADDRESSOF(v) + _INTSIZEOF(v) )

这个地址的内容是未知的,所以就可能出现乱码或崩溃。

二. 解决方案

要解决这个问题,我们只需要做到一点,在调用StringCchVPrintf、vsprintf、vswprintf、_vstprintf、printf这样的一系列函数输出固定字符串时,一定不要将固定字符串传入到pszFormat参数,如:

StringCchVPrintf(szBuf, 512, "我想输出单纯的%s,我是错误的格式示范");  // 错误的

这个时候,单纯的%s中的%s已经不在单纯。
正确的做法是:

StringCchVPrintf(szBuf, 512, "%s", "我想输出单纯的%s,我是正确的格式示范"); 

同理,下面的调用方式也是错误的、危险的:

std::string strInfo = GetInfo();
printf(strInfo.c_str());


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部