_countof和sizeof

_countof和sizeof

    最近在网上搜代码,找到一些不错的源码,作为我的比赛项目的参考。不过看代码的时候发现一个很重要的问题,很多人忽略(包括我经常看的XX的视频,还有我自己)。这个问题虽然小,不过有时候可以要了C/C++程序的命。

    在函数的说明文档里,有些时候某个函数的某个参数的说明是这样:

/* Maximum length of zSql in bytes. */

    有的函数又是这样写的:

The size of the lpFilename buffer, in TCHARs.

    一个in bytes和一个in TCHARS(或in chars),他们有什么区别?其实区别很大,in bytes表示以字节为单位,in tchars表示传入的是数组长度。这又涉及到编码问题。

    C/C++里面有宽字符(wchar_t)和窄字符(char)两种字符类型。每个char占1个字节,每个wchar_t占两个类型。tchar是一个通用类型,如果我们在工程设置里打开宽字节,tchar就被解析成wchar_t,否则就被解析成char。

    我们写windows程序一般都是用tchar类型作为我们的字符类型。比如定义一个TCHAR szBuf[256];就是一个字符数组。(如果没开启宽字符,则被解析成char szBuf[256],和我们平时写的程序一样)

    1.在没开启宽字符(unicode)的时候

    因为char只占用1个字节,所以char szBuf[256]占用256个字节,即:

    sizeof(szBuf) == 256

    _countof(szBuf) == 256  // _countof函数意思是求数组的长度

    得到的是一样的结果。

    所以in bytes的时候,传入sizeof(szBuf)就行了。比如我在《 sqlite的C语言使用 》讲过的sqlite3_prepare函数,第三个参数就传入sizeof(zSql)。

    in CHARs的时候,可以传入_countof(szBuf),也可以直接传入256,。

    在没开启uncide的情况下,就算sizeof和_countof用混了,也不影响程序最终运行。因为结果都是256.

    2.在开启了宽字节UNICODE的时候

    sizeof(szBuf) == 512

    _countof(szBuf) == 256

    两者不一样了。因为tchar被解析成wchar_t,一个wchar_t占两个字节。如果这时候,函数里用混的话,可能会出现意想不到的结果。

    比如大家读这段有问题的代码:

int _tmain(int argc, _TCHAR* argv[])
{
    TCHAR strDir[10];
    int large = sizeof(strDir);
    int re = GetModuleFileName(NULL,strDir,large);
    return 0;
}

    现在这个GetModuleFileName的用处是获取现在程序运行的目录,得到的信息就保存在strDir里。第三个参数说明就是: The size of the  lpFilename  buffer, in TCHARs.  应该传入_countof(strDir)可是我们现在传入的是sizeof(strDir),传成了字符数组占用空间的大小。调试运行看:

    明明定义的strDir是strDir[10],却装了超过10的数据"F:\program\test_Dir",明显溢出了。

    在一般情况下,这样的溢出不会造成程序崩溃,但如果正好有程序需要用溢出的这块地方的内存,本程序就崩溃了。


    所以我建议大家,在使用此类含有字符串数组长度的函数时,看清楚说明文档中的说明,到底是要传入它的大小还是它的长度。比如这类函数:strcpy_s,strcat_s,wcscpy_s..这种字符串操作的函数都是传入字符串的长度,也就是_countof,以后一定不要错了。

多说一句,一般MSDN里,没有特别说是in bytes的(比如说什么Size of the destination string buffer),一般都是要传入字符串长度。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 服务进程里面去创建带窗口的进程(备忘)

    大菊观
  • SLAM-OpenGL实现rplidar A2激光雷达扫描显示

    Pulsar-V
  • c++ warning C4996

    测试使用发现  #pragma warning(disable:4996)这是有效的方式  #define _CRT_SECURE_NO_DEPRECATE依然...

    用户7886150
  • x32下的DLL隐藏

    原理主要就是PEB 中模块断链. 这里整理下代码.原理可以看下另一篇我写的帖子. https://www.cnblogs.com/iBinary/p/9601...

    IBinary
  • Windows核心编程:第2章 字符和字符串处理

    gongluck
  • Windows客户端C/C++编程规范“建议”——变量和常量

    等级:【要求】 说明:全局变量的滥用和goto的滥用一样,都是一种灾难。它将使得逻辑变得难以调试和控制。

    方亮
  • 让应用程序同时只启动一次

    软件的实现方式或者第三方的依赖只能保证单进程运行,也就是说只能让程序同一时间启动一个进程。

    河边一枝柳
  • 基于SOUI开发一个简单的小工具

    Duilib 很久不维护了,而很多不同的分支,似乎都不太维护。微信 Windows 的版本是基于 Duilib 进行开发的,说明应该还是很广泛的。

    meteoric
  • gh0st源码分析与远控的编写(二)

    上次说了那么多,基本上就是一个叫“大局观”的东西,只有脑子里有了一个软件的设计、运行思路,才能把一个一个类写出来,组合在一起。

    phith0n
  • sizeof和strlen的区别

    第一个例子:  char *ss="0123456789";    sizeof(ss)=4, ss是指向字符串常量的字符指针。    sizeof(*s...

    猿人谷
  • C和C++中的sizeof

    青木
  • C++中strlen()和sizeof()的区别

    sizeof(...)是运算符,在头文件中typedef为unsigned int,其值在编译时即计算好了,参数可以是数组、指针、类型、对象、函数等。     ...

    用户7886150
  • C-sizeof和strlen区别,以及sizeof如何计算结构体大小

    对于数组时,strlen是判断’\0’为标志结尾的,而sizeof则计算的是数组整个空间 示例如下:

    张诺谦
  • sizeof(数组)

    这里就不讨论一般的数组长度计算了,只说明一下任何数据到了函数的形参中都将退化为指针,所以计算大小的时候,也是计算的指针的大小 直接上代码了 1 // clas...

    用户1215536
  • sizeof用法

    sizeof()功能:计算数据空间的字节数 1.与strlen()比较 strlen()计算字符数组的字符数,以”\0″为结束判断,不计算为’\...

    苦咖啡
  • C/C++ sizeof(下)

    sizeof作用于基本数据类型,在特定的平台和特定的编译器中,结果是确定的,如果使用sizeof计算构造类型:结构体、联合体和类的大小时,情况稍微复杂一些。

    Dabelv
  • C/C++ sizeof(上)

    sizeof是C/C++中的一个操作符(operator),其作用是返回一个对象或者类型所占的内存字节数,使用频繁,有必须对其有个全面的了解。

    Dabelv
  • sizeof小览

    http://blog.csdn.net/scythe666/article/details/47012347

    bear_fish
  • sizeof 知多少?

    稍熟悉C/C++的朋友,对于sizeof肯定不陌生,通过他我们可以知晓某个类型或者实例的内存大小(以字节计),但是如果深入一下sizeof计算的细节,想来大部分...

    用户2615200

扫码关注云+社区

领取腾讯云代金券