`

ZeroMemory、memset 和 “={0}”

 
阅读更多

ZeroMemorymemset 和 “={0}” 三者用于清零操作的区别:

首先是ZeroMemorymemset 的区别:

1、ZeroMemory 是微软的SDK 提供的,memset 属于C Run-time Library 提供的。
因此ZeroMemory 只能用于Windows系统,而memset 还可用于其他系统。

2、ZeroMemory 是一个宏,只是用于把一段内存的内容置零,内部其实是用
memset 实现的,而memset 除了对内存进行清零操作,还可以将内存置成别的字符。

3、如果程序是Win32程序而且不想连接c运行时库,那就用ZeroMemory ,如果需要跨平台,那就用memset

所以如果ZeroMemorymemset 用于清零操作,其本质是一样的。

然后说说ZeroMemory 和 “={0}”的区别:

1、ZeroMemory 会将结构中 所有字节置0 ,而“={0}”只会将成员置0 ,其中填充字节不变。

2、一个struct 有构造函数或虚函数时,ZeroMemory 可以编译通过,而“={0}”会产生编译错误。其中,“={0}”的编译错误起到了一定的保护作用,
因为对一个有虚函数的对象使用ZeroMemory 时,会将其虚函数的指针置0 ,这是非常危险的(调用虚函数时,空指针很可能引起程序崩溃)。

参看如下代码:

struct SPerson
{
char c;
float s;
};

class CTestVirtual
{
public :
CTestVirtual (){}

/// 虚函数
virtual int Draw()
{
return 10;
}

int a;
};

int main (int argc, char* argv[])
{
char sztmp[20];
/// 安全操作
ZeroMemory (sztmp, sizeof (sztmp));

/// 安全操作
SPerson sTest = {0};
int i = sizeof (SPerson );

//// 会引起编译错误!
//CTestVirtual otv = {0};

CTestVirtual tv;
/// 危险操作!
ZeroMemory (&tv, sizeof (tv));

/// 因为对象没有使用虚指针调用函数,所以程序运行到这里不会崩溃
tv.Draw();

/// 将对象地址赋给指针
CTestVirtual *pTv = &tv;

//虚函数的指针已经被清零,因此程序运行到这里会引起崩溃!
//错误信息:Unhandled exception at 0x004010b1 in Solution.exe:

//0xC0000005: Access violation reading location 0x00000000.
pTv->Draw();

return 0;
}

因此,在windows平台下,数组或纯结构 使用ZeroMemory 是安全的,而类(class)就使用构造函数进行初始化,不要调用ZeroMemory。


另外,如果一个类的结构中包含STL模板(Vector、List、Map等等),那么使用ZeroMemory对这个类的对象中进行清零操作也会引起一系列的崩溃问题(指针指向内存错误、迭代器越界访问等)。
所以,再次强烈建议:类(class)只使用构造函数进行初始化,不要调用ZeroMemory进行清零操作。

转贴自:http://hi.baidu.com/sa_space/blog/item/cf99aac72e5232d6d10060b5.html

分享到:
评论

相关推荐

    ZeroMemory、memset和 “=0” 的区别.pdf

    。。。

    ZeroMemory、memset和 “=0” 的区别.docx

    。。。

    C++中ZeroMemory、memset危险需慎用

    使用C/C++编程时,常使用ZeroMemory、memset或 “={0}”来对结构体对象进行初始化或清零。然而这三种方式都有各自的特点,使用时需谨慎,否则容易出现严重错误,本人解决一个导致宕机的bug,查了几小时,才发现是由...

    一个串口通信的小程序

    //Set Total Read TimeOut as MAXDWORD (0xFFFFFFFF) TimeOuts.ReadTotalTimeoutConstant = 0; //Read TimeOut Const TimeOuts.ReadTotalTimeoutMultiplier = 0; //Return Riht now //Write TimeOut ...

    屏幕抓取,获取鼠标坐标

    ::ZeroMemory(&os,sizeof(os)); os.dwOSVersionInfoSize=sizeof(os); ::GetVersionEx(reinterpret_cast(&os)); if(os.dwPlatformId==VER_PLATFORM_WIN32_NT && os.dwMajorVersion >=5) { if(os....

    MFC打开文件和文件夹

    // ZeroMemory(&ofn,sizeof(ofn)); // ofn.lStructSize = sizeof(ofn); // ofn.lpstrFile = szFile; // ofn.lpstrFile[0] = TEXT('/0'); // ofn.nMaxFile = sizeof(szFile); // ofn.lpstrFilter = TEXT("all/0*...

    delphi hook动作回放

    Zeromemory(@ST,sizeof(TEventArrs)); ST.EventLogs := 0; end; procedure InsertEventArrs(Var ST: TEventArrs; EvMsg: EVENTMSG); begin ST.EventArr[ST.EventLogs] := EvMsg; Inc(ST.EventLogs); end; ...

    VC6 CListCtrl继承类例子

    nFont.CreateFont(m_fontHeight,m_fontWith,0,0,0,FALSE,FALSE,0,0,0,0,0,0,_TEXT("宋体"));//创建字体 nOldFont = pDC->SelectObject(&nFont); DrawText(lpDrawItemStruct->hDC, lpBuffer, strlen(lpBuffer)...

    可以仿造ip

    我们知道,TCP/IP网络数据全部是通过封装在IP数据包中在Internet网上传送的,也就是封装建立起一个包含IP头和数据的IP数据报。一般来说,网络软件总是以多个32位字产生IP头,即使必须用附加的0填充IP头。IP头包含了...

    断点续传示例源码整理

    ZeroMemory(@bufInfo, SizeOf(bufInfo)); {每次只读一个字符,以免读入了命令外的数据} i := FsocketStream.Read(bufInfo, 1); if i = 0 then Break; strStream.Write(bufInfo, i); if pos(EndStr, strStream.Data...

    MFC通过ado类连接SQL、MYSQL、ACCESS多种数据库

    driverODBC = 0, driverSQLServer, driverACCESS97, driverACCESS2000, driverACCESSXP, driverEND}; 2.连接信息可通过结构体修改 typedef struct DBPARA{ BYTE nDriverType; //驱动类型 BYTE nTimeOut; /...

    Windows下目录监视程序代码

    memset( tmp, 0, sizeof(tmp) ); //ZeroMemory() WideCharToMultiByte( CP_ACP,0,pNotify->FileName,pNotify->FileNameLength/2,tmp,99,NULL,NULL ); strcpy( str1, tmp ); if(pNotify->...

    Monitor Audio Volume Levels 监视音量

    rc = mixerOpen(&hMixer, 0,0,0,0); if (MMSYSERR_NOERROR != rc) { // Couldn‘t open the mixer. } // Initialize MIXERLINE structure. ZeroMemory(&mxl,sizeof(mxl)); mxl.cbStruct = sizeof(mxl); // Specify ...

    wce下ping的例子

    memset(acPingBuffer, '*', sizeof(acPingBuffer)); PICMP_ECHO_REPLY pIpe = (PICMP_ECHO_REPLY)GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT, sizeof(ICMP_ECHO_REPLY) + sizeof(acPingBuffer)); if (pIpe == 0...

    Delphi 创建高权限进程

    OldTokenPrivileges.Privileges[0].Attributes := TokenPrivileges.Privileges[0].Attributes or SE_PRIVILEGE_ENABLED; AdjustTokenPrivileges(hToken, False, OldTokenPrivileges, ReturnLength, ...

    socket编写windows和linux通讯程序-源码

    } ZeroMemory(&server,sizeof(server)); server.sin_family=AF_INET; server.sin_port=htons(USERPORT); server.sin_addr.s_addr=htons(INADDR_ANY); if(bind(s,(struct sockaddr *)&server,...

    仿windows关机功能界面

    ZeroMemory(&bmInfo,sizeof(bmInfo)); bmInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmInfo.bmiHeader.biWidth = bm.bmWidth; bmInfo.bmiHeader.biHeight = bm.bmHeight; bmInfo.bmiHeader...

    微信机器人

    0x0 首先要打开微信进程 wchar_t wxPath[] = LC:\\Program Files (x86)\\Tencent\\WeChat\\WeChat.exe; STARTUPINFO si = { 0 }; PROCESS_INFORMATION pi = { 0 }; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si)...

    delphi代码参考

    if GetFileVersionInfo(pchar(FileName), 0, 4096, pointer(buf)) then if VerQueryValue(buf, '\', pointer(sver), i) then begin ma:= sVer^.dwFileVersionMS shr 16; mi:= sver^.dwFileVersionMS and $0000...

    Delphi简体转繁体—繁体转简体

    Len := MultiByteToWideChar(936, 0, pGBCHTChar, -1, nil, 0); GetMem(pGBCHSChar, Len * 2 + 1); ZeroMemory(pGBCHSChar, Len * 2 + 1); //GB CHS -> GB CHT LCMapString($804, LCMAP_SIMPLIFIED_CHINESE, ...

Global site tag (gtag.js) - Google Analytics