memcpy小尝试

itoa

int a=10;
char b[10];
itoa(a,b,2);//二进制显示
printf("%s/n",b);

小地址←大地址的拷贝

#include<math.h>
#include<stdio.h>
#include <string.h>
#include<iostream>
using namespace std;

typedef  unsigned char u8;
typedef  unsigned short int u16;
typedef  unsigned long int u32;
typedef  unsigned long long int u64;

//memcpy逐字拷贝
//void *memcpy(void *dest, const void *src, size_t n);
//从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中
void try_memcpy_1()
{
	u8 a1[10];//int8//1
	u16 a2[10];//int16//2
	u32 a4[10];//int32//int//4
	u64 a8[10];//int64//8
	
	u64 a8E1 = 0;//1 to 8 
	u64 a8E2 = 0;//2 to 8 
	u64 a8E4 = 0;//4 to 8 
	u64 a8E8 = 0;//8 to 8 
	
	char b1[1000];char b2[1000];char b4[1000];
	for(int i = 0; i<10;i++)a1[i] = 1;// = 0xf0;
	for(int i = 0; i<10;i++)a2[i] = 1;// = 0xf0f0;
	for(int i = 0; i<10;i++)a4[i] = 1;// = 0xf0f0f0f0;
	for(int i = 0; i<10;i++)a8[i] = 1;// = 0xf0f0f0f0f0;

    cout<<endl<<"big address ← small address"<<endl;
	cout<<"copy 2 bites"<<endl;//2 char to a8 , 
	memcpy ( &a8E1 ,a1 , 2 ) ;//小内存拷至大内存,大存小
	itoa(a8E1,b1,2);
	cout<<"a8E1 = "<< b1;
	cout<<" = "<< a8E1;cout<<"\t : 2 bites,2 number "<<endl;
	
	memcpy ( &a8E2 ,a2 , 2 ) ;//小内存拷至大内存
	itoa(a8E2,b2,2);
	cout<<"a8E2 = "<< b2;
	cout<<" = "<< a8E2;cout<<"\t : 2 bites,1 number "<<endl;
	
	memcpy ( &a8E4 ,a4 , 2 ) ;//小内存拷至大内存
	itoa(a8E4,b4,2);
	cout<<"a8E4 = "<< b4;
	cout<<" = "<< a8E4;cout<<"\t : 2 bites,1/2 number "<<endl;
	
	memcpy ( &a8E8 ,a8 , 2 ) ;//小内存拷至大内存
	itoa(a8E8,b4,2);
	cout<<"a8E8 = "<< b4;
	cout<<" = "<< a8E8;cout<<"\t : 2 bites,1/4 number "<<endl<<endl;

	cout<<"copy 4 bites"<<endl;
	memcpy ( &a8E1 ,a1 , 4 ) ;//小内存拷至大内存,大存小
	itoa(a8E1,b1,2);
	cout<<"a8E1 = "<< b1;
	cout<<" = "<< a8E1;cout<<"\t : 4 bites,4 number "<<endl;
	
	memcpy ( &a8E2 ,a2 , 4 ) ;//小内存拷至大内存
	itoa(a8E2,b2,2);
	cout<<"a8E2 = "<< b2;
	cout<<" = "<< a8E2;cout<<"\t : 4 bites,2 number "<<endl;
	
	memcpy ( &a8E4 ,a4 , 4 ) ;//小内存拷至大内存
	itoa(a8E4,b4,2);
	cout<<"a8E4 = "<< b4;
	cout<<" = "<< a8E4;cout<<"\t : 4 bites,1 number "<<endl;
	
	memcpy ( &a8E8 ,a8 , 4 ) ;//小内存拷至大内存
	itoa(a8E8,b4,2);
	cout<<"a8E8 = "<< b4;
	cout<<" = "<< a8E8;cout<<"\t : 4 bites,1/2 number "<<endl<<endl;

	cout<<"copy  8 bites"<<endl;
	memcpy ( &a8E1 ,a1 , 8 ) ;//小内存拷至大内存,大存小
	itoa(a8E1,b1,2);
	cout<<"a8E1 = "<< b1;
	cout<<" = "<< a8E1;cout<<"\t : 8 bites,8 number "<<endl;
	
	memcpy ( &a8E2 ,a2 , 8 ) ;//小内存拷至大内存
	itoa(a8E2,b2,2);
	cout<<"a8E2 = "<< b2;
	cout<<" = "<< a8E2;cout<<"\t : 8 bites,4 number "<<endl;
	
	memcpy ( &a8E4 ,a4 , 8 ) ;//小内存拷至大内存
	itoa(a8E4,b4,2);
	cout<<"a8E4 = "<< b4;
	cout<<" = "<< a8E4;cout<<"\t : 8 bites,2 number "<<endl;
	
	memcpy ( &a8E8 ,a8 , 8 ) ;//小内存拷至大内存
	itoa(a8E8,b4,2);
	cout<<"a8E8 = "<< b4;
	cout<<" = "<< a8E8;cout<<"\t : 8 bites,1 number "<<endl<<endl;
}

结果:
1>
1> big address ← small address
1> copy 2 bites
1> a8E1 = 100000001 = 257 : 2 bites,2 number
1> a8E2 = 1 = 1 : 2 bites,1 number
1> a8E4 = 1 = 1 : 2 bites,1/2 number
1> a8E8 = 1 = 1 : 2 bites,1/4 number
1>
1> copy 4 bites
1> a8E1 = 1000000010000000100000001 = 16843009 : 4 bites,4 number
1> a8E2 = 10000000000000001 = 65537 : 4 bites,2 number
1> a8E4 = 1 = 1 : 4 bites,1 number
1> a8E8 = 1 = 1 : 4 bites,1/2 number
1>
1> copy 8 bites
1> a8E1 = 1000000010000000100000001 = 72340172838076673 : 8 bites,8 number
1> a8E2 = 10000000000000001 = 281479271743489 : 8 bites,4 number
1> a8E4 = 1 = 4294967297 : 8 bites,2 number
1> a8E8 = 1 = 1 : 8 bites,1 number

1. 拷贝4个字节8个字节,效果一样没影响,实际数据有不一样。
2. 按字节拷贝。

大地址←小地址的拷贝

void try_memcpy_2()
{
	cout<<endl<<"small address ← big address"<<endl;
	u8 b1E2 = 0;//int8
	u8 b1E4 = 0;//int8
	u8 b1E8 = 0;//int8//1
	u16 d2=0xfa;//int16//2
	u32 d4=0xfbfa;//int32//int//4
	u64 d8=0xfdfcfbfa;//int64//8
	char c2[100];char c4[100];char c8[100];
	
	u8 n = 0;
	switch(n)
	{
		case 0:
			cout<<"copy 1 bites"<<endl;
			memcpy ( &b1E2 ,&d2 , 1 ) ;itoa(b1E2,c2,2);
			cout<<"b1E2 = "<< c2<<endl;
			memcpy ( &b1E4 ,&d4 , 1 ) ;itoa(b1E4,c4,2);
			cout<<"b1E4 = "<< c4<<endl;
			memcpy ( &b1E8 ,&d8 , 1 ) ;itoa(b1E8,c8,2);
			cout<<"b1E8 = "<< c8<<endl<<endl;
			
			n++;
			b1E2 = 0;b1E4 = 0;b1E8 = 0;
			memset(c2,0,100);memset(c4,0,100);memset(c8,0,100);//数组清空
		
		case 1:
			cout<<"copy 2 bites"<<endl;
			memcpy ( &b1E2 ,&d2 , 2 ) ;itoa(b1E2,c2,2);
			cout<<"b1E2 = "<< c2<<endl;
			memcpy ( &b1E4 ,&d4 , 2 ) ;itoa(b1E4,c4,2);
			cout<<"b1E4 = "<< c4<<endl;
			memcpy ( &b1E8 ,&d8 , 2 ) ;itoa(b1E8,c8,2);
			cout<<"b1E8 = "<< c8<<endl<<endl;
			
			n++;
			b1E2 = 0;b1E4 = 0;b1E8 = 0;
			memset(c2,0,100);memset(c4,0,100);memset(c8,0,100);//数组清空
		
		case 2:
			cout<<"copy 4 bites"<<endl;
			memcpy ( &b1E2 ,&d2 , 4 ) ;itoa(b1E2,c2,2);
			cout<<"b1E2 = "<< c2<<endl;
			memcpy ( &b1E4 ,&d4 , 4 ) ;itoa(b1E4,c4,2);
			cout<<"b1E4 = "<< c4<<endl;
			memcpy ( &b1E8 ,&d8 , 4 ) ;itoa(b1E8,c8,2);
			cout<<"b1E8 = "<< c8<<endl;
			cout<<"high address overflow ... "<<endl;

	}

}

结果:
1> small address ← big address
1> copy 1 bites
1> b1E2 = 11111010
1> b1E4 = 11111010
1> b1E8 = 11111010
1>
1> c2[0]=1
1> c2[0]= copy 2 bites
1> b1E2 = 11111010
1> b1E4 = 11111010
1> b1E8 = 11111010
1>
1> c2[0]=1
1> c2[0]= copy 4 bites
1> b1E2 = 11111010
1> b1E4 = 11111010
1> b1E8 = 11111010
1> high address overflow …

拷贝一个大地址到小地址,高位溢出,只剩下低位的数据

向前拷贝&&向后拷贝

//csdn上借鉴的代码
void try_memcpy_3()
{
	u8 buf[15] = {0};
	u8 buf1[15] = {0};
	u8 dst_buf[15] = {0};
 
	for(u8 i = 0; i < 15; i ++)
	{
		buf[i] = i;
		buf1[i] = i;
	}		
 
	printf("src buf  = ");
	for(int i = 0; i < 15; i ++)printf("%d ", buf[i]);

	printf("\nsrc buf1 = ");
	for(int i = 0; i < 15; i ++)printf("%d ", buf1[i]);

	//不同BUFF之间拷贝
	memcpy(dst_buf, buf, 15); 
	printf("\n\n10 from buf copy to dst buf, dst_buf = ");
	for(int i = 0; i < 15; i ++)printf("%d ", dst_buf[i]);


	//同一个BUFF向后拷贝
	memcpy(buf + 4, buf + 3, 10); //buf[3]→buf[4]
	printf("\n10 from buf + 3 copy to buf + 4, buf = ");
	for(int i = 0; i < 15; i ++){
		printf("%d ", buf[i]);
		//buf[i] = 0;
	}

	//同一个BUFF向前拷贝
	memcpy(buf1, buf1 + 3, 10);//buf[3]→buf[0]
	printf("\n*10 from buf1 + 3 copy to buf1, buf1 = ");
	for(int i = 0; i < 15; i ++)
		printf("%d ", buf1[i]);
    printf("\n向后拷贝wrong");
	
}

结果:
1> src buf = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
1> src buf1 = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
1>
1> 10 from buf copy to dst buf, dst_buf = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
向后拷贝有误:
1> 10 from buf[3] copy to buf[4], buf = 0 1 2 3 3 4 5 6 6 8 9 10 10 12 14
向前拷贝无误:
1> *10 from buf1[3] copy to buf1[0], buf1 = 3 4 5 6 7 8 9 10 11 12 10 11 12 13 14

注意向后拷贝的使用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`memcpy()`函数是一个基本的内存复制函数,在C语言标准库中提供,主要用于在不改变目标内存区域原有数据的情况下,从源内存区域复制指定大小的数据到目标内存区域。 ### `memcpy()`函数简介 #### 标准定义 在ANSI C90和后续版本的标准中,`memcpy()`函数的原型通常是这样的: ```c void *memcpy(void *dest, const void *src, size_t n); ``` 这里的参数说明如下: - `dest`: 目标地址指针。 - `src`: 源地址指针。 - `n`: 需要复制的字节数。 #### 功能描述 `memcpy()`函数将`src`所指向的连续字节块复制到由`dest`指针指向的内存中。复制的长度是`n`个字节。如果`dest`和`src`之间存在交叉边界(即它们跨越了一个进程的地址空间界限),那么`memcpy()`的行为是未定义的。通常情况下,`memcpy()`不会检查是否有足够的内存空间来进行复制操作;因此,如果目标缓冲区太短而无法容纳所有数据,程序可能会损坏目标区域或其他内存,并可能导致程序崩溃或安全漏洞。 #### 使用注意事项 - **安全性**: `memcpy()`不检查缓冲区是否足够大,这有可能导致溢出。使用前应确保目标缓冲区有足够的空间接收数据。 - **性能考虑**: 对于小型数组或固定大小的数据块,直接使用位操作进行复制可能比使用`memcpy()`更快。然而,这种做法需要对底层架构有深入理解并且可能不如使用高级API直观易懂。 - **跨平台兼容性**: 虽然大多数现代操作系统上`memcpy()`的行为一致,但在某些嵌入式系统或低级环境中,其行为可能有所不同,因此编写跨平台安全的代码时需谨慎。 ### 示例代码 ```c #include <stdio.h> #include <string.h> int main() { char src[] = "Hello"; char dest; // 尝试复制字符串到目标缓冲区 if (memcpy(dest, src, sizeof(src)) != NULL) { printf("Copied string successfully.\n"); } else { printf("Failed to copy string.\n"); } printf("Source string: %s\n", src); printf("Destination string: %s\n", dest); return 0; } ``` 在这个例子中,我们尝试从`src`复制到`dest`,但由于`dest`的大小刚好等于`src`,所以实际上不需要额外的空间,这个例子仅用于演示目的。 ### 相关问题: - `memcpy()`与`memmove()`的区别是什么? - 怎样避免在使用`memcpy()`时发生内存越界错误? - 当我们需要复制不同类型的变量时应该注意什么? 以上讨论了`memcpy()`函数的基础知识以及一些重要的使用细节和注意事项。了解这些可以帮助程序员更安全、更高效地使用该函数进行内存操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值