惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

C
Check Point Blog
O
OpenAI News
WordPress大学
WordPress大学
Jina AI
Jina AI
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
酷 壳 – CoolShell
酷 壳 – CoolShell
月光博客
月光博客
阮一峰的网络日志
阮一峰的网络日志
量子位
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园_首页
IT之家
IT之家
Last Week in AI
Last Week in AI
Vercel News
Vercel News
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
B
Blog
MongoDB | Blog
MongoDB | Blog
小众软件
小众软件
P
Proofpoint News Feed
Application and Cybersecurity Blog
Application and Cybersecurity Blog
MyScale Blog
MyScale Blog
Schneier on Security
Schneier on Security
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
N
News and Events Feed by Topic
Google Online Security Blog
Google Online Security Blog
N
News | PayPal Newsroom
Hacker News - Newest:
Hacker News - Newest: "LLM"
Google DeepMind News
Google DeepMind News
aimingoo的专栏
aimingoo的专栏
Apple Machine Learning Research
Apple Machine Learning Research
宝玉的分享
宝玉的分享
The GitHub Blog
The GitHub Blog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Recent Announcements
Recent Announcements
L
LINUX DO - 最新话题
TaoSecurity Blog
TaoSecurity Blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
F
Fortinet All Blogs
罗磊的独立博客
Forbes - Security
Forbes - Security
人人都是产品经理
人人都是产品经理
J
Java Code Geeks
H
Heimdal Security Blog
Help Net Security
Help Net Security
V
V2EX
Security Latest
Security Latest
W
WeLiveSecurity
Attack and Defense Labs
Attack and Defense Labs
H
Help Net Security

博客园 - 蓝色星宇

PCB优化设计(二) 转载 (转载)linux下tar.gz、tar、bz2、zip等解压缩、压缩命令小结 [转]为何有濒死经验的人都会变得无私大爱? 关于TV Dongle的功能设计和思考【图】(转载) 标题:常用贴片元件封装(转载) Open Cell(转载) Windows Phone开发工具初体验(转载) SMD贴片元件的封装尺寸(转) STM32 printf 函数原型 调试错误:No Algorithm found for(转载) SD/TF 引脚 追踪“善恶有报” 解开生命健康福寿秘密(转载) JPG文件结构分析---转载 超薄纳米纸张 比钢强250倍--转载 热磁性储存系统---转载 TFT LCD数据存储为BMP文件的C语言代码 STM32 USB IAP 步骤 BMP文件结构的探索----转载自WhatIf GPS NMEA-0183协议详解 ----转载
Memset、Memcpy、Strcpy 的作用和区别(转)
蓝色星宇 · 2012-05-15 · via 博客园 - 蓝色星宇

Posted on 2012-05-15 02:39  蓝色星宇  阅读(6362)  评论()    收藏  举报

(1) Memset
  原型:   extern void *memset(void *buffer, int c, int count);              
  用法:  #include <string.h>           

   功能: 把buffer所指内存区域的前count个字节设置成字符 c。           
  说明: 返回指向buffer的指针。用来对一段内存空间全部设置为某个字符
              例如:     
                    char a[10];                        
                    memset(a, '\0', sizeof(a));               
        memset可以方便的清空一个结构类型的变量或数组。               
             如:struct    _test{  char s[10];      
                                          int x;      
                                          int y;
                                        };        
    变量     struct _test    st;              
(1)一般清空st的方法如下:
st.s[0] = '\0'; st.x =0;   st.y =0;               
(2) 用memset方法如下:               
             memset(&st,0,sizeof(struct _test));         
    数组:  struct _test     st[10];               
  memset(st,0,sizeof(struct _test)*10);  //清空方法
//memset 源码的实现 C语言
#include <mem.h>
void* memset(void* s, int c, size_t n)
{
     unsigned char* p = (unsigned char*) s;

     while (n > 0)
       {
               *p++ = (unsigned char) c;
                --n;
       }

      return s;
  }



(2)memcpy
原型:extern void *memcpy(void*dest,void*src,unsignedintcount);              用法: #include <string.h>              
功能: 由src所指内存区域复制count个字节到dest所指内存区域。            
说明: src和dest所指内存区域不能重叠,函数返回指向dest的指针.可以拿它拷贝任何数据类型的对象。   
             例如:  char a[10],b[5];              
                        memcpy(b, a, sizeof(b));             /*注意如果用sizeof(a),会造成b的内存地址溢出*/
(3) Strcpy   
    原型: extern char *strcpy(char *dest,char *src);                  
    用法: #include <string.h>                    
    功能: 把src所指由NULL结束的字符串复制到dest所指的数组中。               
    说明: src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳 src的字符串.返回指向dest的指针。                    
               例如:   char a[100],b[50];
                          strcpy(a,b);
                 如用   strcpy(b,a);
  要注意a中的字符串长度(第一个‘\0’之前)是否超过50位,如超过,则会造成b的内存地址溢出。
    假如有如下代码,请问输出为多少?
            #include "stdio.h"
            main()
                {  char dest[3];
                    char str[6]="Hello";

               strcpy(dest,str);
                    printf("%s\n",dest);

              }
        编译输出如下结果:
        Hello                  //没有输出乱码,有点怪怪的为什么?
       分析:
             1>str中字符串的长度大于dest 的内存长度3.为什么str字符串还能完拷贝到dest 中呢?
      来看看 strcpy的 源代码实现:
char   *strcpy(char   *strDest,const   char   *strSrc)   
{   
        assert((strDest!=NULL)&&(strSrc   !=NULL))   //判断指针是否合法,即分配内存,指向某块确定区域
        char   *address   =   strDest;               //记住目标地址的起始值
        while((*strDest++   =   *strSrc++)!='\0')   //先拷贝,后判断,这样就不用在拷贝完了后,再加一句
              NULL;                   // *strDest = '\0'; -->即加一个结束符.因为字符串结束已拷贝了.
              return   address;      //返回目标首地址的值。            
               }

        //从上面的代码可以看出,strcpy函数,假定strDest的内存空间是足够可以放下strSrc的内容的.
        //也就是说使用者,在使用strcpy函数时,应使 (strDest内存空间)>=  (strSrc内存空间)     
        // 在调用   strcpy(dest,str);  时,while((*strDest++   =   *strSrc++)!='\0')   没有判断strDest的内存是否够,而是将srtSrc的内容直接拷贝到strDest,当拷到'\0'就结束.
        //因此在使用printf("%s\n",dest);  时 输出遇到'\0'时停此输出.所以会输出: Hello

    (4) 三者区别                    
           memset   主要应用是初始化某个内存空间。                  
           memcpy   是用于copy源空间的数据到目的空间中。                  
           strcpy   用于字符串copy,遇到‘\0’,将结束。                  
如果理解了这些,就能知道它们的区别:                 
       例如初始化某块空间的时候,用到memcpy,那么就显得笨拙                 
    int    m[100]                     
memset((void*)m,0x00,sizeof(int*100);             //Ok!                     
memcpy((void*)m,"\0\0\0\0....",sizeof(int)*100);    //Not Ok
一.函数原型   
    strcpy    extern char *strcpy(char *dest,char *src);   
    #include <string.h>   
   功能:把src所指由NULL结束的字符串复制到dest所指的数组中   
   说明:  src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。    返回指向dest的指针   
    memcpy   extern void *memcpy(void *dest,void *src,unsigned int count);  
    #include <string.h>   
    功能:由src所指内存区域复制count个字符串到dest所指内存区域.   
    说明:src和dest所指内存区域不能重叠,函数返回指向dest的指针.      
    memset    extern void *memset(void *buffer,int c,int count);   
    #include <string.h>   
    功能:把buffer所指内存区域的前count个字节设置成字符c   
   说明:返回指向buffer的指针.
  二.区别   

memset 用来对一段内存空间全部设置为某个字符,一般用于在对定义的字符串初始化为' '或者'\0';     
           例: char a[100];           memset(a,'\0',sizeof(a));        
memcpy 是用来做内存拷贝,可以用来拷贝任何数据类型的对象,可以指定拷贝的数据长度;   
             例:       char a[100],b[50];            
                       memcpy(b,a,sizeof(b));   
   //注意:如果使用sizeof(a),会造成内存溢出            
   mem是一段内存,他的长度,必须自己记住.memcpy是见着什么拷贝什么。         
strcpy 就只能拷贝字符串,它遇到'\0'就结束拷贝;      
            例:char a[100],b[50];               strcpy(a,b);              
            如用strcpy(b,a)要注意a中的字符串长度(第一个'\0'之前) 是否超过50,如果超过,则会造成b的   内存溢出.
      它是不会拷贝'\0'的,所以一般还有加一个语句:               *a='\0';   
三.使用技巧  

  memset 可以方便的清空一个数据结构的变量或数组.      
        如:         struct sample_struct  {  
                                  char   csName[16];               
                                  int      iSeq;              
                                  int       iType;        
                                    };        
       对于变量        
        struct sample_struct   stTest;        
                一般情况下,初始化stTest的方法:         
                         stTest.csName[0]='\0';         
                         stTest.iSeq=0;         
                         stTest.iType=0;     
         而用memset:        
                 memset(&stTest,0,sizeof(struct sample_struct));   
                    如果是数组:     
                     struct sample_struct   TEST[100];     
                     memset(TEST,0,sizeof(struct sample_struct)*100);