将内存复制到标准::复制

Copy Memory to std::copy

本文关键字:复制 内存 标准      更新时间:2023-10-16

我正在尝试将所有CopyMemory函数转换为std::copy函数。

它适用于copymemory和memcpy,但不适用于std::copy。谁能告诉我我做错了什么或如何解决它?

template<typename T>
void S(unsigned char* &Destination, const T &Source)
{
//CopyMemory(Destination, &Source, sizeof(T));
std::copy(&Source, &Source + sizeof(T), Destination);      //Fails..
Destination += sizeof(T);
}
template<typename T>
void D(T* &Destination, unsigned char* Source, size_t Size)
{
//CopyMemory(Destination, Source, Size);
std::copy(Source, Source + Size, Destination);
Source += sizeof(T);
}
template<typename T>
void D(T &Destination, unsigned char* Source, size_t Size)
{
//CopyMemory(&Destination, Source, Size);
std::copy(Source, Source + Size, &Destination);
Source += sizeof(T);
}

我还认为我可以执行以下操作将迭代器转换为指针:

std::string Foo = "fdsgsdgs";
std::string::iterator it = Foo.begin();
unsigned char* pt = &(*it);

那么我将如何将指针转换为迭代器? :S

我用来测试 memcpy/copymem vs std::copy 的代码如下(如果它有效,它打印 7 个......如果它不起作用,则打印随机数):

#include <windows.h>
#include <iostream>
#include <vector>
#include <typeinfo>
using namespace std;
typedef struct
{
int SX, SY;
uint32_t Stride;
unsigned long ID;
int TriangleCount;
} Model;
template<typename T>
void S(unsigned char* &Destination, const T &Source)
{
CopyMemory(Destination, &Source, sizeof(T));
Destination += sizeof(T);
}
template<typename T>
void S(unsigned char* &Destination, const std::vector<T> &VectorContainer)
{
size_t Size = VectorContainer.size();
for (size_t I = 0; I < Size; ++I)
S(Destination, VectorContainer[I]);
}
void S(unsigned char* &Destination, const Model &M)
{
S(Destination, M.SX);
S(Destination, M.SY);
S(Destination, M.Stride);
S(Destination, M.ID);
S(Destination, M.TriangleCount);
}
template<typename T>
void D(T* &Destination, unsigned char* Source, size_t Size)
{
CopyMemory(Destination, Source, Size);
Source += sizeof(T);
}
template<typename T>
void D(T &Destination, unsigned char* Source, size_t Size)
{
CopyMemory(&Destination, Source, Size);
Source += sizeof(T);
}
template<typename T>
void D(std::vector<T> &Destination, unsigned char* Source, size_t Size)
{
Destination.resize(Size);
for(size_t I = 0; I < Size; ++I)
{
D(Destination[I], Source, sizeof(T));
Source += sizeof(T);
}
}
void D(Model* &Destination, unsigned char* Source)
{
D(Destination->SX, Source, sizeof(Destination->SX));
D(Destination->SY, Source, sizeof(Destination->SY));
D(Destination->Stride, Source, sizeof(Destination->Stride));
D(Destination->ID, Source, sizeof(Destination->ID));
D(Destination->TriangleCount, Source, sizeof(Destination->TriangleCount));
}
long double* LD = new long double[25000];
std::vector<Model> ListOfModels, ListOfData;
void ExecuteCommands()
{
switch(static_cast<int>(LD[1]))
{
case 1:
{
LD[2] = 2;
unsigned char* Data = reinterpret_cast<unsigned char*>(&LD[3]);
Model M; M.SX = 1; M.SY = 3; M.Stride = 24; M.ID = 7; M.TriangleCount = 9;
Model K; K.SX = 3; K.SY = 21; K.Stride = 34; K.ID = 9; K.TriangleCount = 28;
ListOfModels.push_back(M);
ListOfModels.push_back(K);
S(Data, ListOfModels);
}
break;
}
}
void* GetData()
{
unsigned char* Data = reinterpret_cast<unsigned char*>(&LD[3]);
D(ListOfData, Data, LD[2]);
cout<<ListOfData[0].ID;        //Should print 7 if it works.
return &ListOfData[0];
}

int main()
{
LD[1] = 1;
ExecuteCommands();
GetData();
}

这段代码有很多问题,几乎不可能知道从哪里开始。在许多情况下,这些错误是如此基本,以至于它暴露了对你应该做什么的严重误解。您正在编写的代码类型对于经验丰富的C++程序员来说是危险的;您在代码中犯的错误表明您远未体验。

停止尝试做你想做的事情。

但是,让我们以您的代码为例。

std::copy(&Source, &Source + sizeof(T), Destination);      //Fails..

首先,让我们谈谈C++中的指针。

如果你有一个指向某种类型的T的指针,假设T *t,这样做t + 1不会将指针移过一个字节。这是这里基本的指针算术;t + 1将把它转移sizeof(T);这就是指针从 C 早期开始的工作方式,更不用说C++了。

SourceT&,所以&SourceT*。因此,向其添加sizeof(T)将使指针递增sizeof(T) * sizeof(T)。那不是你想要的。

其次,std::copy不是memcpystd::copy用于将一个值集合(由输入迭代器对定义)复制到由输出迭代器定义的另一个值集合中。std::copy要求输入迭代器的value_type可隐式转换为输出迭代器的value_type

T*value_type,即所讨论的输入迭代器,是一个T;T*指向Ts。char*value_type,输出迭代器,是charstd::copy将尝试有效地做到这一点:

char *val;
T *t;
*val = *t;

即使忽略这两个指针未初始化的事实,这也是没有意义的。除非T有一个operator char转换运算符,否则你不能简单地拿一个T把它推到一个char。因此,您会收到编译错误。正如你应该的。

如果您确实有一些T并希望将其复制到适当大小的char*数组中(反之亦然),则std::copy不是您需要的工具。您想要的工具是std::memcpy.std::copy用于复制对象,而不是复制字节。