C++如何拷贝多份相同大小的数据以及拷出多份相同大小的数据(memcpy的用法)

一、memcpy相关用法

C++ memcpy函数的用法比较简单,memcpy拷贝数据的时候,只需要传递拷贝数据的指针(4个字节)以及需要拷贝数据的大小就可以了。但是如何进行大数据的拷贝呢?以及如何拷贝若干份相同的数据(例如1000张图像)呢?

首先memcpy的原型如下:

void* memcpy(void* _Dst,const void* _Src,size_t _Size);

参数详解:

_Dst:新缓冲区。

_Src:复制的缓冲区。

_Size:要复制的字节数。

因为参数是void*类型,所以可以将其他任意的类型转换为void*类型,但是拷贝的大小会受到_Size的控制。

 

假设我们有1000张100*100的灰度图像,那么我们如何将这些数据拷贝到指定的目标中呢?具体如下

1、将若干份图像数据拷贝到指定目标中

// 申请需要开辟的目标缓冲区的大小
const int ImageSize = 100 * 100;
const int ImageNums = 1000;

char* pData = new char[ImageNums * ImageSize ];  // 1000张100*100的灰度图像
int index = 0;
for(int i = 0; i < ImageNums ; i++)
{
    // 假设图像的数据从文件中读取
    CString strImagePath;
    strImagePath.Format("imageData%d",i);
    Mat src = imread(strImagePath,0);  // 灰度图像加载 大小为100*100
    // 将图像数据拷贝到指定的缓冲区中
    memcpy(pData + index,src.data,ImageSize);
    index += ImageSize;
}


// 处理完之后,对pData做相应的处理之后,释放所开辟的空间
delete[] pData;
pData = NULL;

2、将指定目标中的数据读取出来,拆分为一张张图像(1中是将所有的图像存到指定的缓存中,那么我们如何从缓存中取出每一张图像呢)

// 申请需要开辟的目标缓冲区的大小
const int ImageSize = 100 * 100;
const int ImageNums = 1000;

char* pData = new char[ImageNums * ImageSize ];  // 1000张100*100的灰度图像
int index = 0;
for(int i = 0; i < ImageNums ; i++)
{
    // 假设图像的数据从文件中读取
    CString strImagePath;
    strImagePath.Format("imageData%d",i);
    Mat src = imread(strImagePath,0);  // 灰度图像加载 大小为100*100
    // 将图像数据拷贝到指定的缓冲区中
    memcpy(pData + index,src.data,ImageSize);
    index += ImageSize;
}


// 上述将1000张图像存入指定的缓存中,那么我们如何将图像取出来呢
index = 0;
for(int i = 0; i < ImageNums ; i++)
{
    Mat dst(100,100,CV_8UC1); // 创建图像
    memcpy(dst.data,pData + index,ImageSize);
    index += ImageSize;

    // 已经将图像数据拷贝到指定图像中了
    // 接下来对图像做相关的处理
}

// 释放指针
delete[] pData;
pData = NULL;

其实图像数据也可以替换成其他任意类型的数据,如结构体等。

二、我所踩过的一些坑

假设我现在需要传递两个float的数据,但是我们函数上面是中char*指针传递的,代码如下

#include <iostream>
using namespace std;
float calc(char *data)
{
	float fdata[2];
	fdata[0] = data[0]; // 将data[0]赋值给第一个float
	fdata[1] = data[1]; // 将data[1]赋值给第二个float
	return fdata[0] * fdata[1];
}

int main()
{
	float data[2] = {1,2};
	float ret = calc((char*)data);
	cout << ret << endl;
}

但是最终的结果不正确,它的结果是0,那么原因在哪里呢?

虽然我们传递参数的时候将float类型的指针转换为char*类型的指针,但是一个float占四个字节,而一个char占一个字节,所以问题就处在char* data这里,data[0]占一个字节,data[1]占一个字节,而传过来的是两个float,即八个字节,但是我们只使用了八个字节的前两位,即data[0],data[1]。

那么我们如何修改呢?

#include <iostream>
using namespace std;
float calc(char *data)
{
	float fdata[2];
	memcpy((char*)fdata,data,sizeof(float)*2);
	return fdata[0] * fdata[1];
}

int main()
{
	float data[2] = {1,2};
	float ret = calc((char*)data);
	cout << ret << endl;
}

使用memcpy进行拷贝操作,将8个字节全部拷贝进来就OK了。

以上仅为个人工作中处理问题所遇到的,因此将其记录下来,分享给大家,让大家少走一些弯路! 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值