将内存复制到std :: copy [英] Copy Memory to std::copy

查看:63
本文介绍了将内存复制到std :: copy的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

它与copymemory和memcpy一起使用,但不适用于std :: copy.谁能告诉我我在做什么错或如何解决?

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

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

How would I convert pointers to iterators then? :S

我用来测试memcpy/copymem与std :: copy的代码如下(如果可以,它将输出7;如果不可以,则显示随机数):

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

推荐答案

此代码存在很多错误,几乎不可能知道从哪里开始.而且错误在许多情况下是如此基础,以至于背叛了人们对应该做的事情的严重误解.您正在编写的代码类型对于经验丰富的C ++程序员是危险的.您在代码中犯的错误表明您还没有经验.

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..

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

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

如果您有指向某个类型 T 的指针,那么假设 T * t ,则执行 t + 1 不会将指针移动一个字节.这是基本的指针算法内容. t + 1 会将其移动 sizeof(T);自C语言诞生以来,指针就是这样工作的,更不用说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 T& ,所以& Source T * .因此,向其添加 sizeof(T)将使指针增加 sizeof(T)* sizeof(T).那不是你想要的.

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.

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

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.

所讨论的输入迭代器 T * value_type T T * 指向 T s.输出迭代器 char * value_type char . std :: copy 将尝试有效地做到这一点:

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;

即使忽略这两个指针未初始化的事实,这也没有任何意义.除非 T 具有 operator char 转换运算符,否则您不能简单地采用 T 并将其推入 char .因此,您会收到一个编译错误.如您所愿.

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.

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

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.

这篇关于将内存复制到std :: copy的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆