memcpy(strcpy和memcpy的区别)
本文目录
- strcpy和memcpy的区别
- memcpy的用法
- 关于memcpy()函数
- memcpy 如何定义使用
- C语言中memcpy函数用法
- memcpy函数怎么用
- memcpy是什么意思
- memcpy在什么情况下会失败
- C语言中复制一个结构体只能使用memcpy的方法吗感觉有些麻烦,有别的方法吗
- 既然有memcpy_s这种安全实现,为啥不禁用危险的memcpy或者更新memcpy源码
strcpy和memcpy的区别
strcpy和memcpy主要有以下3方面的区别。1、复制的内容不同。strcpy只能复制字符串,而memcpy可以复制任意内容,例如字符数组、整型、结构体、类等。2、复制的方法不同。strcpy不需要指定长度,它遇到被复制字符的串结束符"\0"才结束,所以容易溢出。memcpy则是根据其第3个参数决定复制的长度。3、用途不同。通常在复制字符串时用strcpy,而需要复制其他类型数据时则一般用memcpy
memcpy的用法
是覆盖函数名: memcpy 功 能: 从源source中拷贝n个字节到目标destin中 用 法: void *memcpy(void *destin, void *source, unsigned n); 程序例: #include 《stdio.h》 #include 《string.h》 int main(void) { char src = "******************************"; char dest = "abcdefghijlkmnopqrstuvwxyz0123456709"; char *ptr; printf("destination before memcpy: %s\n", dest); ptr = memcpy(dest, src, strlen(src)); if (ptr) printf("destination after memcpy: %s\n", dest); else printf("memcpy failed\n"); return 0; }
关于memcpy()函数
该例子说明几个问题1.mem开头的函数基本上都是对内存操作的,它们不管内存里放的是什么数据,只要给出长度,它们就操作。不像strcpy、strcmp等函数一定以’\0’结尾,而且是字符。mem可以操作可见字符、不可见字符、控制字符等,任意数据都可以。2.memcpy是内存复制函数原型:void*memcpy(void*dest,voidconst*src,unsignedintlength);功能:从src的起始位置复制length个字节到dst的内存起始位置。你可以用这种方法复制任何类型的值,第3个参数指定复制值的长度(以字节计)。如果src和dst以任何形式出现了重叠,它的结果是未定义的。3.memset函数原型:void*memset(void*a,intval,unsignedintlength);功能:把从a开始的length个字节都设置为值val。例子:memset(buffer,0,SIZE);
memcpy 如何定义使用
楼上怎么了? /* 原型:extern void *memcpy(void *str, void *src, unsigned int count); 头文件:#include 《string.h》 */ 将src的count个字符复制到str区,以’\0’,结束。 定义自己实现吧 它们的原型都封装在.lib里面了
C语言中memcpy函数用法
memset函数用来对一段内存空间全部设置为某个字符,常用于内存空间初始化。将已开辟内存空间s的首n个字节的值设为值c。下面是一个例子#include《stdio.h》#include《string.h》main(){char*s="goldenglobalview";clrscr();memset(s,’g’,6);printf("%s",s);getchar();return0;}c语言memcpy函数原型:externvoid*memcpy(void*dest,void*src,unsignedintcount);用法:#include《string.h》功能:由src所指内存区域复制count个字节到dest所指内存区域。说明:src和dest所指内存区域不能重叠,函数返回指向dest的指针。举例://memcpy.c#include《syslib.h》#include《string.h》main(){char*s="goldenglobalview";chard;clrscr();memcpy(d,s,strlen(s));d=0;printf("%s",d);getchar();return0;}函数strchr()功能:在一个串中查找给定字符的第一个匹配之处\用法:char*strchr(char*str,charc);程序例:#include#includeintmain(void){charstring;char*ptr,c=’r’;strcpy(string,"thisisastring");ptr=strchr(string,c);if(ptr)printf("thecharacter%cisatposition:%d\n",c,ptr-string);elseprintf("thecharacterwasnotfound\n");return0;}
memcpy函数怎么用
c和c++使用的内存拷贝函数,memcpy函数的功能是从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中。从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中C语言中使用#include 《string.h》;C++中使用#include 《cstring》和#include 《string.h》都可以。1.source和destin所指的内存区域可能重叠,但是如果source和destin所指的内存区域重叠,那么这个函数并不能够确保source所在重叠区域在拷贝之前不被覆盖。而使用memmove可以用来处理重叠区域。函数返回指向destin的指针.2.如果目标数组destin本身已有数据,执行memcpy()后,将覆盖原有数据(最多覆盖n)。如果要追加数据,则每次执行memcpy后,要将目标数组地址增加到你要追加数据的地址。注意:source和destin都不一定是数组,任意的可读写的空间均可。
memcpy是什么意思
memoryn.记忆,记忆力; 回忆,往事; 存储器,内存; 复数:memories 例句:1.Why on earth would christopher swallow a memory card? 克里斯多弗干嘛要把记忆卡给吞下呢? 2.What is your favorite memory? 你最美好的回忆是什么?
memcpy在什么情况下会失败
1、memcpy在使用时注意不可用字符串,如果是字符串会导致段错误,可以使用asprintf函数复制字符串,从而导致memcpy的段错误。
2、即memcpy不能拷贝目的地址(dest)和源地址(src)内存空间有重合的部分,更为确切的说应该是当目的地址大于源地址的时候,不能够有重合部分,否则源地址重合部分数据会发生错误。
3、当copy越界时,可能会出现程序异常。
扩展资料:
如果目标数组destin本身已有数据,执行memcpy()后,将覆盖原有数据(最多覆盖n)。如果要追加数据,则每次执行memcpy后,要将目标数组地址增加到你要追加数据的地址。
source和destin所指的内存区域可能重叠,但是如果source和destin所指的内存区域重叠,那么这个函数并不能够确保source所在重叠区域在拷贝之前不被覆盖。而使用memmove可以用来处理重叠区域。函数返回指向destin的指针。
参考资料来源:
百度百科-memcpy
C语言中复制一个结构体只能使用memcpy的方法吗感觉有些麻烦,有别的方法吗
谢邀。
这个问题和我之前发的文章有些相似,上周我在我的C语言学习圈子里简要介绍了一个小窍门,粗略来说就是使用C语言结构体的赋值语法,代替memcpy()语句,以精简代码,大致如下图所示:
有读者看到后,认为C语言结构体的赋值并不等价于 memcpy,也有朋友评论说 b=a 是“浅拷贝”,还有读者提到结构体赋值效率没有memcpy高,那么 b = a 语句被执行后,究竟发生了什么呢?
编写测试C语言代码
得到答案最简单直接的方法就是实验,因此这里给出一段较为完整的C语言代码,用于测试结构体的赋值语句,如下所示。为了讨论主题,下面C语言代码比较精简:
上面这段C语言代码很简单,main() 函数定义了 3 个结构体变量 a, b, c,其中 a 被初始化为 {3, 5},并通过赋值语句拷贝给 b,memcpy() 拷贝给 c。考察 a,b,c 占用的内存里的值,从最终“拷贝效果”上分析赋值语句和memcpy()的异同。
查看内存值
查看上述C语言程序中的变量 a, b, c 的值方法很多,最直接的方法就是使用 printf() 函数逐字节打印,不过这样就略显繁琐了,使用 GDB 工具调试C语言程序更简单些。
首先,输入 gcc t.c -g 编译上述C语言代码,得到可执行文件 a.out。接着,就可以使用 gdb 调试了:
首先在 main() 函数处下断点,然后输入 run 命令让C语言程序运行起来:
可以发现程序停在第 10 行了,此时变量 a,b, c 还没有被赋值或者 memcpy。我们先看一下结构体 s 的 size,可以直接在 gdb 环境查看:
发现 sizeof(struct s) 等于 16,这主要是因为C语言编译器为了提升效率,对结构体 s 的两个成员做了内存对齐处理。所以,虽然 char 型的 c 成员实际上只需 1 个字节内存空间,但是因为成员 l 占用 8 字节内存空间,所以编译器在 c 后面预留了 7 个字节。
读者 @Romi1984 认为 C语言结构体赋值拷贝和 memcpy 拷贝不等价,因为“赋值的话,对齐字节不会拷贝”。他的意思应该是 c 后面预留的 7 个字节不会被拷贝,那是不是如此呢?在执行 b =a; 语句之前,我们先来查看 a,b,c 在内存里的值:
能够看出,此时变量 a,b,c 的内存值并不完全相同。输入 next 命令,使C语言程序运行到第 16 行,也即 return 0; 语句处,此时赋值语句以及 memcpy 语句都被执行完毕,再查看 a,b,c 的内存值,得到如下输出:
发现变量 a, b, c 的值完全相同,包括结构体 s 的 c 成员后内存对齐的 7 个字节,这说明读者 @Romi1984 说的“对齐字节不会被拷贝”是不准确的,至少就本例而言,C语言结构体 s 的赋值拷贝和 memcpy 拷贝效果上是等价的。
效率问题
虽然通过 gdb 查看内存值,我们发现C语言结构体的赋值拷贝和 memcpy 拷贝效果是等价的,但是,读者 @quser225816904 认为,这两种方式的效率是不一样的。
那究竟是否如此呢?得到答案最直接的办法就是衡量这两条语句的执行时间。不过由于这一“执行时间”很短,难以计量,我们采取其他方法:输入下面的命令,查看C语言程序的汇编代码。
# objdump -dSa.out
从C语言程序的汇编代码可以看出,b = a; 和 memcpy() 语句都是 4 条 mov 语句,这说明两种拷贝方式的效率相差无几,所以读者 @quser225816904 的说法也是不准确的。另外,从C语言程序的汇编代码也能更直观的看出 b = a; 和 memcpy() 是等价的。
读者也可以通过多次执行 b = a 和 memcpy 语句,对比两种拷贝方式的效率。
“深拷贝”和“浅拷贝”
前面两位读者分别从执行效果和执行效率两个角度质疑了C语言结构体赋值拷贝和memcpy拷贝的等价性,也有读者认为赋值拷贝只是“浅拷贝”,那么究竟是否如此呢?
首先,先要明白“浅拷贝”和“深拷贝”概念,这两个概念 Java,C++,js 等编程语言程序员应该比较熟悉,在C语言中倒是不怎么常提。细究这两个概念的区别并不是本文的重点,所以这里粗略的对“浅拷贝”和“深拷贝”做如下区分,对于把变量 a 拷贝给 b:
如果拷贝后,b 的内容完全等于 a,并且两个变量在内存中是独立的,则称此次拷贝为“深拷贝”。如果靠背后,只是通过 b 能够访问 a 中的内容,a 的内容改变时,b 的“内容”也随之改变,则称此次拷贝为“浅拷贝”。
这样看来,就本例而言,b = a;显然是一次“深拷贝”,因为 a, b 在内存中彼此独立,并且拷贝后,b 的内容和 a 的内容完全相同。那C语言的结构体赋值拷贝一定是“深拷贝”吗?我们将结构体 s 新增一个指针成员 buf:
对 a 的初始化也做相应修改,相关C语言代码如下,请看:
为了讨论主题,上述C语言代码没有做错误处理。现在 b = a; 还是“深拷贝”吗?读者如果做了实验,应该会发现,b 的 buf 成员本身在内存中的确独立于 a 的 buf 成员,但是它指向的内存却与 a 的 buf 成员指向的内存是同一块,所以这时 b = a; 不再是纯粹的“深拷贝”了。
小结
本节主要讨论了C语言结构体的赋值语法可以用于拷贝,并针对之前读者的几个典型问题做了较为详细的实例探讨。不过,C语言是一门非常灵活的编程语言,可能同样的一条语句,在不同的环境下执行结果是不一样的,这一点本文最后的讨论就是一个实例。应该明白,本文举的例子仅是为了抛砖引玉,展示遇到问题该如何分析的方法,学习C语言,应该乐于做实验尝试才对。
欢迎在评论区一起讨论,质疑。文章都是手打原创,每天最浅显的介绍C语言、linux等嵌入式开发,喜欢我的文章就关注一波吧,可以看到最新更新和之前的文章哦。
既然有memcpy_s这种安全实现,为啥不禁用危险的memcpy或者更新memcpy源码
往简单了说 就是为了兼容老代码!也就是此前编写的代码。
如果禁用memcpy,那么旧代码必须进行修改,才能在新版本中编译通过。而一旦你把旧代码修改了,在旧的编译环境中,又编译不过了!所以不能禁用。
如果更新memcpy的源码,可能需要使用到一些新的语言特性之类的,这些新特性可能导致代码在新旧编译环境中的效果出现差异!进而出现系统bug!所以也不能轻易的重写!
导致memcpy和memcoy_s共存这样一个状况,最根本的原因,是在早期设计这些API的时候,没办法预见到后续的问题。只有等到这些问题出现,并且很严重的时候,才不得不采用这种打补丁的方式来处理。
对于强迫症患者来说,这个确实难以忍受!但是这种策略,在软件开发中经常使用。接口兼容,是非常常见的事情!
更多文章:
联想如果倒闭了,谁受益最大?联想在市场营销中的应用不能实现以下哪个功能
2023年12月7日 07:00
纽曼mp4老款(旧款的纽曼MP4Windows7不支持怎么办)
2024年9月4日 01:20
阿普利亚srmax250(阿普利亚srmax250踏板的评测如何)
2023年3月4日 07:00
华盖星入命好不好(华盖在各柱的意思,华盖命的前世只有非常高贵的人)
2024年6月5日 21:19
小米9se和小米9(小米9和小米9se内存分别是多少,从小到大)
2024年5月20日 19:53
lenovo a60手机(联想手机a60上不去网,一直网络错误)
2024年6月30日 08:13
vivov1发布时间(请我VIVO第一台手机发布的日期是11月几日)
2023年3月9日 08:20
索尼h300使用教程视频(索尼dsc_h300相机如何使用教程)
2024年9月2日 09:10
ios10用不了最新版微信(更新了ios10,微信更新用不了了,怎么办)
2024年7月17日 15:28
解析包出现问题无法安装怎么办(安装软件显示安装包异常不能安装怎么办)
2024年7月18日 16:20