1、使用memset初始化:

memset函数原型:void * memset(void *ptr,int value,size_t num);  作用:用于为地址ptr开始的num个字节赋值value

typedef struct s1
{SOCKET     m_Socket;SOCKADDR_IN m_ClientAddr;//初始化s1(){m_Socket = INVALID_SOCKET;//SOCKADDR_IN本身也是个结构体可以使用memset方法初始化memset(&m_ClientAddr, 0, sizeof(m_ClientAddr));}
};struct Stu
{int nNum;bool bSex;char szName[20];char szEmail[100];//这样初始化也可以Stu(){memset(this, 0, sizeof(Stu));//或者下面的格式//memset(&nNum, 0, sizeof(Stu));}
};

2、

使用ZeroMemory的初始化

ZeroMemory只有将数据置零的功能,在windows平台下,数组或纯结构使用ZeroMemory是安全的

typedef struct _PER_IO_CONTEXT
{OVERLAPPED     m_Overlapped;   //每一个重叠网络操作的重叠结构(针对每一个Socket的每一个操作,都要有一个)SOCKET          m_sockAccept;   //这个网络操作所使用的SocketWSABUF            m_wsaBuf;       //WSA类型的缓冲区,用于给重叠操作传参数char           m_szBuffer[MAX_BUFFER_LEN]; //WSABUF里具体存字符的缓冲区OPERATION_TYPE    m_OpType;       //标识网络操作的类型//初始化_PER_IO_CONTEXT(){ZeroMemory(&m_Overlapped, sizeof(m_Overlapped));ZeroMemory(m_szBuffer, MAX_BUFFER_LEN);m_sockAccept = INVALID_SOCKET;m_wsaBuf.buf = m_szBuffer;m_wsaBuf.len = MAX_BUFFER_LEN;m_OpType = NULL_POSTED;}//释放掉Socket~_PER_IO_CONTEXT(){if (m_sockAccept != INVALID_SOCKET){closesocket(m_sockAccept);m_sockAccept = INVALID_SOCKET;}}//重置缓冲区内容void ResetBuffer(){ZeroMemory(m_szBuffer, MAX_BUFFER_LEN);}
}PER_IO_CONTEXT,*PPER_IO_CONTEXT;

3、注意事项:

(1)  不能认为memset可以赋值为任意的值,因为memset函数在赋值时是逐个字节赋值的,如果是一个int类型的数组,比如int a[10];其中每个元素占有4字节的大小,如果执行memset(a,1,sizeof(a));则此时并不是将数组里面所有值都赋值为1,而是将每个元素的4个字节分别赋值为1,则其二进制大小为0000 0001 0000 0001 0000 0001 0000 0001,也就是将4组值为1的二进制连接起来,所以此时数组中每个元素大小为16843009,与其预期不符,但是可以使用0或者-1为int类型数组赋值,因为0对应的二进制为0000,-1对应的二进制位1111,所以在逐字节赋值的时候不会产生赋值错误。

(2)  可以对char类型数组进行不同值的赋值,因为char类型正好只占用1字节,赋的值只要为char类型则不会出现(1)中的错误

(3)  ZeroMemory和memset在清零时回将结构体中所有字节置为0,如果结构体中含有虚函数或结构体成员中有虚函数,则会将虚函数指针置为0,如果后续程序通过指针调用虚函数,则这个空指针会造成崩溃,另外如果一个类的结构中包含STL模板(Vector、List、Map等),那么使用ZeroMemory对这个类的对象中进行清零操作也会引起一系列的崩溃问题(指针指向内存错误、迭代器越界访问等),所以建议:类只使用构造函数进行初始化,不要调用ZeroMemory进行清零操作

#include <iostream>
#include <string>
using namespace std;struct s1
{int i;virtual void  fun(int a){i = a;}
};int main()
{s1 s;s.i = 10;s.fun(100);cout << s.i << endl;  //100memset(&s, 0, sizeof(s));s.fun(88);cout << s.i << endl;  //88(&s)->fun(99);  //此处引发了异常 __vfptr = 0x00000000,崩溃cout << s.i << endl; //并不能打印出数值
}

如上程序,在置0后,只有使用指针来调用该虚函数时会产生崩溃,通过对象调用则不会产生崩溃,并且如果函数只是普通函数而非虚函数,则置0后不会发生错误,因为普通函数没有虚函数指针,虚函数指针才会占用空间,所以在置0时被置为空指针。

ZeroMemory和memset的区别:
(1)  ZeroMemory是微软的SDK提供的,memset属于C Run-time Library提供的,因此ZeroMemory只能用于Windows系统,而memset还可用于其他系统
(2)  ZeroMemory是一个宏,只用于把一段内存的内容置零,内部其实是用memset实现的,而memset除了对内存进行清零操作,还可以将内存置成别的字符
(3)  如果程序是Win32程序而且不想连接C运行时库,那就用ZeroMemory,如果需要跨平台,那就用memset

ZeroMemory和“={0}”的区别:
(1)  ZeroMemory会将结构中所有字节置0,而“={0}”只会讲成员置0,其中填充字节不变
(2)  一个struct有构造函数或虚函数时,ZeroMemory可以编译通过,而“={0}”会产生编译错误,其中,“={0}”的编译错误起到了一定的保护作用,因为对一个有虚函数的对象使用ZeroMemory时,会将其虚函数的指针置0,这是非常危险的(调用虚函数时,空指针很可能引起程序崩溃)

部分借鉴自:https://www.cnblogs.com/lidabo/archive/2013/01/07/2848701.html
————————————————
版权声明:本文为CSDN博主「寂寂寂寂寂蝶丶」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/SwordArcher/article/details/83417950

使用ZeroMemory、memset对结构体、数组的初始化相关推荐

  1. python 结构体数组_python实现结构体数组(初始化并赋值)

    标签: C语言中结构体数组概念及定义 一个结构体变量可以存放一个学生的一组信息,可是如果有 10 个学生呢?难道要定义 10 个结构体变量吗?难道上面的程序要复制和粘贴 10 次吗? 很明显不可能,这 ...

  2. python数组赋值给变量_python实现结构体数组(初始化并赋值)

    C语言中结构体数组概念及定义 一个结构体变量可以存放一个学生的一组信息,可是如果有 10 个学生呢?难道要定义 10 个结构体变量吗?难道上面的程序要复制和粘贴 10 次吗? 很明显不可能,这时就要使 ...

  3. c语言字符结构数组初始化,C语言结构体数组初始化问题

    C语言结构体数组指定初始化器时,下面的三种方法,只有第三种可以,但是第一,二种,我看不出语法上哪错了,编译器DEVc++会报错 [Error] C99 designator 'num_insur' o ...

  4. 【C语言】结构体指针与结构体数组

    目录 一.结构体指针 二.结构体数组 1.结构体数组的定义 2.结构体数组的初始化 3.结构体数组的引用 4.结构体数组指针 一.结构体指针 与一般指针类似结构体也可以使用结构体指针进行引用使用.结构 ...

  5. 【结构体】 结构体引用、结构体数组指针、包含结构的结构体

    目录 一.概念.变量的定义 初识结构体 结构体变量的定义.引用结构体类型的初始化 二.结构体的数组 认识结构体数组 初始化结构体数组 三.结构体指针 初识结构体指针 指向结构体数组的指针 结构体作为函 ...

  6. c语言调用dll实例 结构体传参,Matlab调用Dll,对于自定义结构体数组如何传参? - 程序语言 - 小木虫 - 学术 科研 互动社区...

    %[例子1] % Matlab调用DLL,整形数组传参 v = [1,22,33;44,-56,67]; pv = libpointer('int16Ptr',v); m = get(pv,'Valu ...

  7. C语言结构体变量和结构体数组-学习笔记(十六)

    一.结构体变量 1.结构体概念 将不同类型的数据组合成一个有机的整体即为结构体.结构体由许多组织在一起的数据项组成,这些数据项不需要属于同一类型. 2.结构体类型及结构体变量定义 (1)结构体类型声明 ...

  8. 结构体变量以及结构体数组

    1.概述 C 语言允许用户自己指定这样一种数据结构,它由不同类型的数据组合成一个整体,以便引用,这些组合在一个整体中的数据是互相联系的,这样的数据结构称为结构体,它相当于其它高级语言中记录. 声明一个 ...

  9. 【HDU】1305 Immediate Decodability(字典树:结构体数组,二维数组,链表/指针)

    一.用的二维数组 #include <iostream> #include <cstring> #include <algorithm> using namespa ...

  10. 【HDU】1251统计难题 (字典树:二维数组,结构体数组,链表,map)

    使用二维数组或者结构体数组都可以,但是在计数的时候有一点点小区别 一.结构体数组 #include <cstdio> #include <cstring> #include & ...

最新文章

  1. android+qq换肤实现,QMUI 换肤 · Tencent/QMUI_Android Wiki · GitHub
  2. java短横线转驼峰_第二讲:Java的运作原理
  3. ./utserver: error while loading shared libraries: libcrypto.so.0.9.8: cannot open shared object file
  4. 当Project xCloud落地移动终端,云游戏靠手游撑起“当打之年”?
  5. 区块链时代的拜占庭容错:Tendermint(五)
  6. Unity3d之AssetBundle打包与读取
  7. python模块request怎么安装_安装 request模块
  8. python求解三角形第三边长
  9. php替换图片_php实现图片上传并进行替换操作
  10. 源码解析:init-method、@PostConstruct、afterPropertiesSet孰先孰后
  11. fabric.js自定义字体的引入
  12. Win8彻底关闭UAC
  13. 12306验证码破解思路分享
  14. 使用uboot + minicom串口协议下载镜像文件
  15. qt 修改.exe文件图标_如何在没有错误的情况下更改压缩的.EXE文件上的图标
  16. 向左还是向右,网约车聚合平台还是高精度地图数据收集站
  17. 如何利用C#/C++调取创蓝253短信验证码
  18. 英语背单词有用吗_英语背单词真的有用吗?
  19. 初探数通网络开放可编程简介
  20. DenseNet 算法

热门文章

  1. Xcode 5 单元测试(一)使用XCTest进行单元测试
  2. 柳传志:任正非比我敢冒险 但他摔下来会很重
  3. Gitcafe使用笔记
  4. 获取Android手机已安装应用程序的安装包
  5. jquery中each的全面用法
  6. 新手学大数据、机器学习相关开发技术,蜡炬教育提醒会经历这几个阶段
  7. 如何利用无源蜂鸣器制作音乐
  8. 江苏姑娘做开颅手术丈夫陪着剃光头,这爱情是真的存在。
  9. PHP递归法因式分解,C++实现 递归算法 - 赏金问题 - 整数因式分解
  10. 敏捷开发绩效管理之一:序言及“敏捷开发是否考核个人”(绩效考核)