首页 > 其他分享 >字符串memcpy

字符串memcpy

时间:2022-12-08 17:39:51浏览次数:34  
标签:src dst void char person 字符串 memcpy


memcpy函数

字符串memcpy_字节数

原型函数1:

void *memcpy(void *dst, const void *src, size_t len)
{
if(NULL == dst || NULL == src){
return NULL;
}

void *ret = dst;

if(dst <= src || (char *)dst >= (char *)src + len){
//没有内存重叠,从低地址开始复制
while(len--){
*(char *)dst = *(char *)src;
dst = (char *)dst + 1;
src = (char *)src + 1;
}
}else{
//有内存重叠,从高地址开始复制
src = (char *)src + len - 1;
dst = (char *)dst + len - 1;
while(len--){
*(char *)dst = *(char *)src;
dst = (char *)dst - 1;
src = (char *)src - 1;
}
}
return ret;
}

原型函数2:

       void* memcpy(void* dest, void* source, size_t count)

      {

           void* ret = dest;

          //copy from lower address to higher address

          while (count--)

                  *dest++ = *source;

           return ret;

      }

原型函数3:

void *memcpy(void *des,const void *src,size_t len)

{

        char * result =des;

        const char * from = src;

        assert(des&&src);

        while(len--)

        {   

                *(result++) = *(from++);

        }   

        return des;

}



1、调用memcpy函数前未初始化缓冲区

当调用memcpy函数时,如果第三个参数设置的复制字节数小于buffer的字节数,buffer尾部剩余字节中的内容是不可预知的,从而可能导致严重错误。所以,最好在使用memcpy函数前调用memset函数,将buffer中所有位置初始化为0。

memcpy函数是纯字节复制,不管字节中的内容,并且源地址和目标地址都需要确保有大于第三个参数指定的大小,否则复制会产生溢出,此外,源地址和目标地址所指向的存储空间也不能重叠。

2、这个函数不会检查参数dest与参数src所指向的数组(或其他类型)是否具有同样的空间。所以如果复制的字节数n超出了dest的空间容量,或者n超出src的容量,这个函数是不会进行判断的,这样就会很危险。这样,就需要程序员自己检查是否有溢出的情况出现。

同时要注意第三个参数长度,大多利用sizeof(src)计算其值,单要留心数值类型,总之是以字节为单位复制的。

3、(1)可以拷贝任何类型的对象,因为函数的参数类型是void*(未定义类型指针),也就是说传进去的实参可以是int*,short*,char*等等,
但是由于函数拷贝的过程是一个字节一个字节的拷贝的,所以实际操作的时候要把void*强制转化为char*,这样在指针加的时候才会保证每次加一个字节,

4、strcpy与memcpy的区别:

1、复制的内容不同。strcpy只能复制字符串,而memcpy可以复制任意内容,例如字符数组、整型、结构体、类等。

2、复制的方法不同。strcpy不需要指定长度,它遇到被复制字符的串结束符"\0"才结束,所以容易溢出。memcpy则是根据其第3个参数决定复制的长度。

3、用途不同。通常在复制字符串时用strcpy,而需要复制其他类型数据时则一般用memcpy

 

memcpy 在结构体中的妙用:

struct {
char name[40];
int age;
} person, person_copy;


int _tmain(int argc, _TCHAR* argv[])
{
char myname[] = "Pierre de Fermat";


/* using memcpy to copy string: */
memcpy(person.name, myname, strlen(myname) + 1);
person.age = 46;


/* using memcpy to copy structure: */
memcpy(&person_copy, &person, sizeof(person));


printf("person_copy: %s, %d \n", person_copy.name, person_copy.age);


getchar();

return 0;
}


标签:src,dst,void,char,person,字符串,memcpy
From: https://blog.51cto.com/u_6958388/5922937

相关文章

  • 字符串总结2
    作者:​​xyw_Eliot​​char*和int,float等的格式化转换从字符串中提取指定类型数字或子串,这种情形也是非常的常见。大部分的情形都可以用sscanf()​和 sprintf() 这两......
  • iOS开发_颜色转十六进制字符串
    /***@briefUIColor转#ffffff格式的16进制字符串**@return格式为#ff0000的16进制字符串*/-(NSString*)hex_String{constCGFloat*components=C......
  • 10、 数组和字符串的应用 编程实现以下功能:采用选择法排序对数组a中的10个元素按
    这是按照书上的最客观的一种做法,但我个人觉得实在是太那个啥了,有很多没有必要的地方,浪费时间......
  • python字符串
    python学习字符串处理方法1.大小写转换函数作用str.lower()全小写str.upper()全大写str.capitalize()第一个字符大写str.swapcase()大写转小写,小......
  • 什么是字符串常量池?
    链接:http://www.importnew.com/10756.html在理解字符串常量前,我们先熟悉一下如何创建一个字符串,在Java中有两种方法可以创建一个字符串对象:使用new......
  • 教你如何进行数仓字符串、二进制、十六进制互转
    本文分享自华为云社区《​​GaussDB(DWS)字符串、二进制、十六进制互转​​》,作者:你是猴子请来的救兵吗。概述现网中遇到很多小伙伴不清楚字符串与进制之间的转换方法,其实......
  • 教你如何进行数仓字符串、二进制、十六进制互转
    本文分享自华为云社区《GaussDB(DWS)字符串、二进制、十六进制互转》,作者:你是猴子请来的救兵吗。概述现网中遇到很多小伙伴不清楚字符串与进制之间的转换方法,其实在Gaus......
  • Powershell 包含字符串
    字符串包含的三种方法 Console.WriteLine("请输入第一个字符串");           stringstr1=Console.ReadLine();           Console.WriteLine......
  • android jni 字符串的处理
    说明:java中使用的是utf-16 c++中使用的utf-8;同时JNI提供一系列java和c++之间转换的方法,具体如下。extern"C"JNIEXPORTjstringJNICALLJava_com_yuanrenxue_cours......
  • 力扣14 寻找字符串数组中最长公共前缀
    力扣14寻找字符串数组中最长公共前缀题目:编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀,返回空字符串""。示例1:输入:strs=["flower","flow",......