memset()函数原型为:
void* _cdecl memset(void* _Dst,int _Val,size_t _Size);
函数功能:将_Dst所指区域的前size_t个字节均初始化为_val,调用时需要引用string.h头文件
memset()函数多用于数组和结构体这种占用内存比较大的数据结构的初始化,如果没有对其进行初始化,常常会产生一些野值。
此外,读者可能对_cdcel和size_t比较陌生,这里稍微解释下,其中_cdecl表示C/C++和MFC程序默认使用的调用约定:所有参数从右到左依次入栈,这些参数由调用者清除,称为手动清栈。
(这里不详细说明,后续会写一篇关_cdecl、_stdcall、_fastcall的文章,读者可去我的主页查看),size_t是宏定义unsigned int或unsigned _int64的替换体
2.使用memset()函数 2.1 用memset()函数给数组初始化#include
#include
int main(){
int b[10];
memset(b,0,sizeof(b));
for(int i=0;i<10;i++){
printf("%d ",b[i]);
}
}
结果为:
0 0 0 0 0 0 0 0 0 0
memset 一般使用0初始化内存单元,需要注意的是,memset()函数是对size_t个字节进行赋值,而int类型为4个字节,如果写成这样便是错误的:
memset(b,0,10);
正确写法为:
memset(b,0,sizeof(int)*10)
这等价于例中的写法
2.2 用memset()函数给结构体初始化#include
#include
struct Node {
int data[10];
struct Node* next;
};
int main() {
struct Node node;
memset(&node, 0, sizeof(struct Node));
}
通过memset()函数初始化要比挨个对结构体中成员初始化要方便很多。
如果是对结构体数组初始化:
struct Node nodes[10];
memset(nodes,0,sizeof(struct Node)*10);
3.容易忽视的错误
错误1:sizeof(指针)
先来看一个例子:
#include
#include
int main(){
char a[10];
char* str=a;
memset(str,0,sizeof(str));
for(int i=0;i<10;i++){
printf("%d ",str[i]);
}
}
大家觉得结果是什么?是“0 0 0 0 0 0 0 0 0 0”吗?
错误,结果应该是:
0 0 0 0 -52 -52 -52 -52 -52 -52
为什么会这样?因为str是指针变量,无论str指向的是什么类型的变量,str终究只是存储了地址,sizeof(str)永远等于4!所以我们只将前面4个字节置为0,而后面的-52应该是乱码的表示,因为后面六个字节是没有初始化的(关于-52知道的读者可以在评论区留言)
我们平常可以通过指针或数组名来 *** 控数组元素的值,如str[i],a[i],*(str+i)都是正确的写法,但务必主义的是指针和数组名不完全相同,具体区别我会另写一篇文章讲解。
错误2:多字节类型变量赋非0值与想像的不同
还是来看一个例子:
#include
#include
int main(){
int a[10];
memset(a,1,sizeof(a));
for(int i=0;i<10;i++){
printf("%d ",a[i]);
}
}
大家觉得结果是什么呢?是“1 1 1 1 1 1 1 1 1 1”吗?
正确答案为:
memset()函数赋值时,是对数组b的每个字节赋值,所以每个数组元素的值为:
0000 0001 0000 0001 0000 0001 0000 0001
转换为10进制便是16843009
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)