关于memset() 函数的使用

第一次接触了memset() 函数。 感觉的确是一个能够高效的实现对一个array 进行一次性初始化的fancy way。 下面给出介绍:

memset() 函数定义在头文件<<cstring>>中, prototype 如下:

void * memset ( void * ptr, int ch, size_t num );

函数的作用是: fill the first num bytes(注意不是element) of block of memory(由空指针ptr指向) with value.
最后我们会解释这句话的含义。

关于size_t 这个类型, 是定义在C标准库中的。

援引百度百科介绍:

在C++中,设计 size_t 就是为了适应多个平台的 。size_t的引入增强了程序在不同平台上的可移植性。size_t是针对系统定制的一种数据类型,一般是整型(int),因为C/C++标准只定义一最低的位数,而不是必需的固定位数。而且在内存里,对数的高位对齐存储还是低位对齐存储各系统都不一样。为了提高代码的可移植性,就有必要定义这样的数据类型。一般这种类型都会定义到它具体占几位内存等。当然,有些是编译器或系统已经给定义好的。经测试发现,在32位系统中size_t是4字节的,而在64位系统中,size_t是8字节的,这样利用该类型可以增强程序的可移植性。

所以size_t 一般和int 所占用的存储空间是相同的:

#include <iostream>

using namespace std;

int main()
{
    cout << sizeof(size_t) << endl;
    cout << sizeof(int) << endl;
    return 0;
}

运行结果如下:

不难看出, 对于(我的电脑是32位的), int 和 size_t 的空间是相同的。

为了进一步加强对内存的概念, 我又做了如下转型的测试:

#include <iostream>

using namespace std;

int main()
{
    int i = 100;
    cout << sizeof(static_cast<char>(i));
    return 0;
}

运行结果如下:

可见使用转型的时候, 转型后的数据是存储在一个temp 的char 型的变量。 占用的内存当然为1 byte 了。

再看下例:

#include <iostream>

using namespace std;

int main()
{
    int i = 100;
    cout << sizeof(static_cast<char>(i)) << endl;
    cout << sizeof(i);
    return 0;
}

但是转型的时候, 可能会丢失信息。

下面使用memset() 函数。

官方文件中, 对memset() 函数的comment 如下:

.is a very efficient way to set all values of the_array to zero。

首先, 该函数返回初始化后的buffer。

可以通过下图查看memset() 函数去初始化数组与用for loop 对数组初始化这两种方法的所需要的时间的比较:

可见, 随着数组的大小越来越大, memset的效率优势愈发明显。

上述是对char 的形式初始化, 我们可以直接使用大小作为memset第三个参数。 因为char 型数组占用的空间大小(以byte 计数)就是size的值。

但是对于int型的数组, 由于一个int 型的值会占用4 bytes, 所以使用起来会不同。

详见下例:

#include <iostream>

using namespace std;

/* memset example */
#include <iostream>
#include <cstring>

int main ()
{
    int myArray[11];
    char str[] = "almost every programmer should know memset!";

    memset(str,'-',6);
    cout << str << endl;

    memset(myArray, 10, 11 * sizeof(int));
    for(int i = 0; i < 11; i++) {
       cout << myArray[i] << " ";
    }
    cout << endl;

    memset(myArray, 10, sizeof(myArray));
    for(int i = 0; i < 11; i++) {
       cout << myArray[i] << " ";
    }

    return 0;
}

运行结果如下:

问题来了: 对于上例子中, 对char 型数组的初始化, 输出符合预期。 但是对于整型数组却不符合预期, 为什么呢。 答案就是memset 是对于memory block  是一个字节一个字节的赋值。 由于int 型数组一个int元素就有4个bytes, 当然不符合预期了。

相信改为0后就可以了, 另外改为-1 也可以:

#include <iostream>

using namespace std;

/* memset example */
#include <iostream>
#include <cstring>

int main ()
{
    int myArray[11];
    char str[] = "almost every programmer should know memset!";

    memset(str,'-',6);
    cout << str << endl;

    memset(myArray, 0, 11 * sizeof(int)); // 注意不能是<span style="font-family: Arial, Helvetica, sans-serif;">memset(myArray, 0, 11 ); 啊</span>

    for(int i = 0; i < 11; i++) {
       cout << myArray[i] << " ";
    }
    cout << endl;

    memset(myArray, -1, sizeof(myArray));
    for(int j = 0; j < 11; j++) {
       cout << myArray[j] << " ";
    }

    return 0;
}

运行结果如下:

所以memset() 函数不能让我们对数组初始化某一个特定的整数。 Anyway, 可以高效的初始化为0 或者-1 就okay咯。

时间: 2024-08-02 11:59:54

关于memset() 函数的使用的相关文章

memset()函数

1. memset()函数原型是extern void *memset(void *buffer, int c, int count)        buffer:为指针或是数组, c:是赋给buffer的值, count:是buffer的长度. 这个函数在socket中多用于清空数组.如:原型是memset(buffer, 0, sizeof(buffer)) Memset 用来对一段内存空间全部设置为某个字符,一般用在对定义的字符串进行初始化为' '或'/0': 例:char a[100];

strcpy, memcpy, memset函数

一. strcpy函数 原型声明:char *strcpy(char* dest, const char *src); 头文件:#include <string.h> 和 #include <stdio.h> 功能:把从src地址开始且含有NULL结束符的字符串复制到以dest开始的地址空间 说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串. 返回指向dest的指针. 实现代码: char * strcpy(char * strDest,c

透彻分析C/C++中memset函数

原文:http://blog.csdn.net/dan15188387481/article/details/49621447 在C语言中,经常需要对内存进行操作,里面涉及很多函数,但是memset函数的使用有一点需要大家格外注意,这也是我在做项目时遇到过的一个问题,调试了很久才找出来错误. 函数原型是:void *memset(void *s, int ch, size_t n); 函数功能是:将s所指向的某一块内存中的前n个字节的内容全部设置为ch指定的ASCII值, 第一个值为指定的内存地

strcpy,memcpy,memset函数实现

strcpy 实现,只能拷贝字符串 char* strcpy(char* des,const char* source) { char* r=des; assert((des != NULL) && (source != NULL)); while((*des++ = *source++)!='\0'); return r; } memcpy 实现,注意目的地址和源地址重合的情况,以及强制类型转换 void *myMemCopy(void *dest,const void *src,siz

memset函数

常见错误: 第一: 搞反了 ch 和 n 的位置. 一定要记住如果要把一个char a[20]清零,一定是 memset(a,0,20);而不是 memset(a,20,0); 第二: 过度使用memset,我想这些程序员可能有某种心理阴影,他们惧怕未经初始化的内存,所以他们会写出这样的代码: 这里的memset是多余的. 因为这块内存马上就被全部覆盖,清零没有意义. 另:以下情况并不多余,因某些编译器分配空间时,内存中默认值并不为0: 第三: 其实这个错误严格来讲不能算用错memset,但是它

memset函数具体说明

1.void *memset(void *s,int c,size_t n)总的作用:将已开辟内存空间 s 的首 n 个字节的值设为值 c. 2.样例#include void main(){char *s="Golden Global View"; clrscr(); memset(s,'G',6);printf("%s",s); getchar();return 0;} 3.memset() 函数经常使用于内存空间初始化.如:char str[100];mems

C语言中的memset函数和数组指针

代码: 1 #include <iostream> 2 #include <cstring> 3 4 using namespace std; 5 6 int main(){ 7 int a[5] = {1}; 8 memset(a,5,sizeof(a)); 9 cout<<a[0]<<" "<<a[1]<<endl; 10 cout<<a<<" "<<a+

一直误解的memset函数

1.“想当然”导致的后果 今天犯了一个十分低级的错误,在对一个整型数组用memset进行初始化设置所有元素值为1.可是结果却大出所料,很意外啊!接着,我就做了代码测试. #include <iostream> using namespace std; int array1[10001]; int array2[10]; int array3[10]; int main() { memset(array1, -1, 10); memset(array2, 0, 10); memset(array

pow log memset函数

1.计算一个数是几位数: 可以用log10(N)+1:这个函数,其重载形式是 double   res: int  N: res=log10((double)N)+1:应该注意数据都是double类型的. 2.memset 函数: 这个函数赋值的时候是按字节来赋值的,例如 Int   arr[110][110]; memset(arr,1,sizeof(int)):这样数组是不能赋值为   1   的,因为按字节赋值,而在VC中int 类型的数据占四个字节,这样赋值就变成了 二进制   0000

C/C++中memset函数

本文学习参考http://baike.baidu.com/link?url=ZmSyY8ciB_nJt9KM-W2fiEFJrC2mugFsLqRdY2b4pLe8rD_jRXyN7_pj0GBBD2bKyt6Xm-lpUlAO97H94dUYXa 1.memset函数的声明和含义如下: 函数解释:将s所指向的某一块内存中的前n个字节的内容全部设置为 ch 指定的 ASCII值, 第一个值为指定的内存地址,块的大小由第三个参数指定,这个函数通常为新申请的内存做初始化工作, 其返回值为指向s的指针