Chinaunix首页 | 论坛 | 博客
  • 博客访问: 291771
  • 博文数量: 134
  • 博客积分: 667
  • 博客等级: 上士
  • 技术积分: 770
  • 用 户 组: 普通用户
  • 注册时间: 2012-04-08 15:19
文章分类

全部博文(134)

文章存档

2012年(134)

分类:

2012-04-08 15:59:19

原文地址:memset、sizeof知多少? 作者:yulianliu1218


1. memset

     void *memset( void *dest, int c, size_t count );

     所需头文件"memory.h",主要功能是将目标指针dest对应count个字节内存空间的值初始化为c, 这个函数的功能虽然看起来很简单,但是对于初始化分配结构体、数组等类型对应内存空间时,它的效率是极高的。那么看到上面的说明,我们基本了解了 memset可以对分配内存进行初始化。下面请看初始化实例,我们将长度为256的不同类型和不同分配方式下的内存空间对应值赋值为1,下面分别采用4种 方式进行实现:

     #include "stdio.h"

     #include "memory.h"

     void main()

     {

             //方式1

             //////////////////////////////////////////静态数组char型赋值成1////////////////////////////////////////////////////

             char buffer[256];

             memset(buffer, 1, sizeof(buffer));

             ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

             //方式2

             //////////////////////////////////////////静态数组int型赋值成1////////////////////////////////////////////////////

             int buffer[256];

             memset(buffer, 1, sizeof(buffer));

             ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

            //方式3

            //////////////////////////////////////////动态数组char型赋值成1////////////////////////////////////////////////////

             char *buffer;

             buffer = new char[256];

             memset(buffer, 1, sizeof(buffer));

             ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

             //方式4

             //////////////////////////////////////////动态数组int型赋值成1////////////////////////////////////////////////////

             int *buffer;

             buffer = new int[256];

             memset(buffer, 1, sizeof(buffer));

             //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

     }

     那么,上面4种方式运行之后是否实现了我们的要求呢?

     运行上述四种方式对应代码,通过调试我们可以发现,只有方式1才实现了我们的目标,其它3种方式都没有达到我们的要求,那是为什么呢?

     看看上面红色部分标记的语句,我们不难发现,其实memset函数其实是针对字节进行快速初始化的,也就是说它不为管你的内存是char型还是int型,在它看来,你只用告诉它需要初始化内存空间的字节长度,它就将对应的内存空间对应的每个字节全部初始化成相同的整数值,所以方式2操作后buffer对应的内存空间的值就变成了

     buffer[0]~buffer[255]

     0x0101  0x0101 0x0101 .......................0x0101

     所以方式2实际上是将buffer数组里面的每一个元素初始化成了0x0101,即257

     那么方式3和4的错误又在什么地方呢,按理说方式3应该是正确的才对,在这里,我要说,可能大家又忽视了sizeof运算符的用法了,这也是我在一次代码的调试过程中发现自己犯过同样的错误,sizeof是获取变量或者类型(通常是结构体)的字节存储空间大小,所以自然的,方式3和方式4中sizeof(buffer)的值均为4,可能在不同编译环境中,值可能不同,在vc环境下是4,因为此时的buffer只是一个指针变量,简单的说来,buffer也是一个变量,只不过这个变量比较特殊--指针变量,在vc中,指针变量一般用4个字节来存储,所以它们最终操作后的内存空间实际上是将buffer指向的100个字节的char型和int型内存空间对应的前4个字节初始化成1,所以操作后:

     方式3:

     buffer[0] = buffer[1] = buffer[2] = buffer[3] = 1,其余元素未初始化

     方式4:

     buffer[0] = buffer[1] = 0x0101,其余未初始化(如有疑问,请参考方式2的分析)

     所以,虽然memset初始化内存好用,但是我们也不得不注意到,初始化其实是针对字节而言的,一旦出现对非字节内存变量赋值时,我们要谨记,此时的memset只能作为初始化为0操作的功能函数,在实际的代码编写中,一般而言,为了快速对申请的内存进行初始化,我们一般也用memset进行内存对应值初始化为0的操作。

     下面简单说下sizeof运算符,请看下面一段代码,执行之后的输出是多少?

     #include "stdio.h"
     struct TESTSTRUCT
     {
           int *m_pData;    
           unsigned char m_nType; //自动对齐到int
           int m_nCount;
           float m_fScore;
           double m_fAverage;
           bool m_bAllowed;   //自动对齐到double
     };

     void main()
     {
           printf("%d\n", sizeof(TESTSTRUCT));
     }

阅读(2152) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~