Copy Memory to std::copy

旧街凉风 提交于 2021-02-11 16:46:00

问题


I'm trying to convert all my CopyMemory functions to std::copy functions.

It works with copymemory and memcpy but not std::copy. Can anyone tell me what I'm doing wrong or how to fix it?

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);
}

I've also figured that I could do the following to convert iterators to pointers:

std::string Foo = "fdsgsdgs";

std::string::iterator it = Foo.begin();

unsigned char* pt = &(*it);

How would I convert pointers to iterators then? :S

The code I use to test the memcpy/copymem vs std::copy is as follows (It prints 7 if it works.. and random numbers if it doesn't):

#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();
}

回答1:


There are so many things wrong with this code that it's almost impossible to know where to begin. And the errors are in many cases so basic that it betrays a gross misunderstanding of what you should be doing. The kind of code you're writing is dangerous for experienced C++ programers; the errors you've made in your code suggest that you're far from experienced.

Stop trying to do what you're trying to do.

But let's take your code.

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

First, let's talk about pointers in C++.

If you have a pointer to some type T, let's say T *t, doing this t + 1 will not shift the pointer over one byte. This is basic pointer arithmetic stuff here; t + 1 will shift it over by sizeof(T); that's how pointers have worked since the earliest days of C, let alone C++.

Source is a T&, so &Source is a T*. Therefore, adding sizeof(T) to it will increment the pointer by sizeof(T) * sizeof(T). That's not what you want.

Second, std::copy is not memcpy. std::copy is for copying one collection of values (defined by an input iterator pair) into another collection of values defined by an output iterator. std::copy requires that the value_type of the input iterator is implicitly convertible to the value_type of the output iterator.

The value_type of a T*, the input iterator in question, is a T; T*'s point to Ts. The value_type of your char*, your output iterator, is char. std::copy is going to try to do effectively this:

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

Even ignoring the fact that these two pointers are uninitialized, this makes no sense. Unless T has an operator char conversion operator, you cannot simply take a T and shove it into a char. Therefore, you get a compile error. As you should.

If you truly have some T and want to copy it into a char* array of the appropriate size (or vice-versa), std::copy is not the tool you need. The tool you want is std::memcpy. std::copy is for copying objects, not copying bytes.



来源:https://stackoverflow.com/questions/12523153/copy-memory-to-stdcopy

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!