Fork me on GitHub

memset()实现及细节

      memset是计算机中C/C++语言函数。将s所指向的某一块内存中的前n个 字节的内容全部设置为ch指定的ASCII值, 块的大小由第三个参数指定,这个函数通常为新申请的内存做初始化工作, 其返回值为指向s的指针。

      头文件:<memory.h>或<string.h>

void *memset(void *s, int ch, size_t n);

函数解释:将s中前n个字节替换为ch并返回s;

memset:作用是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法。

     

     一维数组的动态分配,初始化和撤销都好说,几乎每一本C++教材都会做出详细的说明。具体如下:

动态分配(例如分配10个单元的): int *array=new int [10];

初始化:memset(array,0,sizeof(array));       (也可以利用一个for循环对其赋值初始化)

撤销:delete [] array;

下面来说二维数组的。

二维数组(n行m列)利用new来进行动态分配实际上相当于对n个m元数组进行动态分配,只不过我们不能一味的按照动态分配一维数组的方法来这项操作。MSVC目前还没有这般的人性化,具体应该这样做:

int **array;
array=new int *[10];
for(int i=0;i<10;i++)
         array[i]=new int [5];


   上面的操作完成了一个10行5列的二维数组array[10][5]的动态分配,可以看到我们先动态分配了一个10单元的数组的指针的指针的首地址**array,然后再对其每个首地址进行遍历,同时完成一个5单元的数组的动态分分配,并把首地址给*array[i],从而最终完成了二维数组array[10][5]的动态分配。我们可以依此类推得到三维以至多维的数组的动态分配方法。

      二维数组的初始化:如果把一维数组初始化办法照搬过来就会发现对于动态分配的二维数组并不适用。这就要理解到memset这个函数三个参数的含义。MSDN对memset的描述如下:

memset

Sets buffers to a specified character.

void*memset(void*dest,intc,size_tcount);

可见memset只能作用于一个一维数组void*dest,因此最好的办法就是和二维数组的动态分配结合起来,new一个,memset一个。具体写法如下:

int **array;
array=new int *[10];
for(int i=0;i<10;i++)

{
         array[i]=new int [5];

       memset(array[i],0,5*sizeof(int));

}

 

编译平台:

 

  Microsoft Visual C++ 6.0

  也不一定就是把内容全部设置为ch指定的ASCII值,而且该处的ch可为int或者其他类型,并不一定要是char类型。例如下面这样:

  int array[5] = {1,4,3,5,2};

  for(int i = 0; i < 5; i++)

  cout<<array[i]<<" ";

  cout<<endl;

  memset(array,0,5*sizeof(int));

  for(int k = 0; k < 5; k++)

  cout<<array[k]<<" ";

  cout<<endl;

  输出的结果就是:

  1 4 3 5 2

  0 0 0 0 0

  后面的表大小的参数是以字节为单位,所以,对于int或其他的就并不是都乘默认的1(字符型)了。而且不同的机器上int的大小也可能不同,所以最好用sizeof()。 

  要注意的是,memset是对字节进行操作,所以上述程序如果改为

  int array[5] = {1,4,3,5,2};

  for(int i = 0; i < 5; i++)

  cout<<array[i]<<" ";

  cout<<endl;

  memset(array,1,5*sizeof(int));// 注意 这里与上面的程序不同

  for(int k = 0; k < 5; k++)

  cout<<array[k]<<" ";

  cout<<endl;

  输出的结果就是:

  1 4 3 5 2

  16843009 16843009 16843009 16843009 16843009

  为什么呢?

  因为memset是以字节为单位就是对array指向的内存的5个字节进行赋值,每个都用ASCII为1的字符去填充,转为二进制后,1就是00000001,占一个字节。一个INT元素是4字节,合一起就是00000001000000010000000100000001,就等于16843009,就完成了对一个INT元素的赋值了。

  所以用memset对非字符型数组赋初值是不可取的!

  例如有一个结构体Some x,可以这样清零:

  memset( &x, 0, sizeof(Some) );

  如果是一个结构体的数组Some x[10],可以这样:

  memset( x, 0, sizeof(Some)*10 );

 

posted @ 2016-06-04 21:51  ranjiewen  阅读(3818)  评论(0编辑  收藏  举报