C ++:结构是否可以正确复制?

时间:2010-01-21 19:46:35

标签: c++ c pointers memcpy

我有一个指向结构的指针,我需要实现一个复制结构的所有内存内容的方法。一般来说,我需要执行结构的深层复制。

这是结构:

typedef struct { 
    Size2f spriteSize;

    Vertex2f *vertices;

    GLubyte *vertex_indices;
} tSprite;

这是我实现的方法应该复制结构:

tSprite* copySprite(const tSprite *copyFromMe)
{

    tSprite *pSpriteToReturn = (tSprite*)malloc( sizeof(*copyFromMe) );

    memcpy(pSpriteToReturn, copyFromMe, sizeof(*copyFromMe) );

    return pSpriteToReturn;
}

问题是我不确定数组“vertices”和“vertex_indices”是否会被正确复制。什么会以这种方式被复制?数组的地址或数组本身?

我应该在复制结构后复制数组吗?或者仅仅复制结构就足够了吗?

这样的事情:

...
pSpriteToReturn->vertices = (Vector2f*)malloc( sizeof(arraysize) );
memcpy(pSpriteToReturn->vertices, copyFromMe->vertices, sizeof(arraysize) );
...

提前谢谢。

7 个答案:

答案 0 :(得分:8)

根据经验,不要在普通代码中使用C ++中的memcpy可能在非常低级别的代码中出现,例如在分配器中) 1)。相反,创建一个合适的复制构造函数并重载operator =(赋值运算符)以匹配它(一个析构函数 - 三个规则:“如果你实现了复制构造函数{{1和析构函数,必须实现所有这三个。)

如果您没有实现自己版本的复制构造函数和赋值运算符,C ++将为您创建默认版本。这些版本将实现一个浅拷贝(很像operator =会做的),即在你的情况下,数组内容将被复制 - 只有指针。


1)顺便提一下,memcpymalloc也是如此。不要使用它们,而是使用free / newnew[] / delete

答案 1 :(得分:3)

这部分取决于您的要求。如果不复制数组,则两个结构都将指向同一个数组,这可能是也可能不是问题。

答案 2 :(得分:3)

您的方案将复制阵列的地址。返回的“copy”tSprite将指向与传入的相同数据(在内存中)。

如果你想要一个真正的深拷贝,你需要手动复制数组(及其元素的任何成员)。

答案 3 :(得分:2)

如果你正在写C ++,那么请记住C ++有newdelete是有原因的。至于问题本身,它取决于你是否想要复制指针或结构本身。如果是后者,你也需要复制它们!

答案 4 :(得分:1)

即使您在普通的C中工作,这也不是正确的复制方法。

在另一个答案中指出,最终会有两个(或更多)结构实例指向同一个Vertext2GLubyte实例,这是不推荐的。

这会导致诸如谁将释放内存分配给Vertext2 GLubyte等问题

Should I copy the arrays after copying the structure? Or is it enough just to copy the structure?

是的,这是正确的方法

答案 5 :(得分:1)

指针本身将被复制,但这意味着两个精灵中的“from”和“to”都是相同的。您还需要手动分配和复制指针指向的内容,但这意味着您还需要知道指针引用的数组有多大。

请注意,除了memcpy之外,您还可以执行'* pSpriteToReturn = * copyFromMe;'这将复制所有成员,但如果您要创建新数组,那么您想要实际复制的tSprites中唯一的部分就是大小。

另一个注意事项是,如果你的精灵总是有固定数量的顶点和顶点索引,你可以在精灵中使这些数组而不是指针。如果你这样做,那么它们将使用memcpy方法和我在上一段中提到的赋值正确复制。

答案 6 :(得分:1)

在C ++中新建并删除堆上的分配。

Sprite *ptr =...;
Sprite *s = new Stripe(*ptr); // copy constructor, shallow copy off pointers
s->member = new Member(*ptr->member); // copy construct sprite member

s->array = new int[4]; //allocate array
std::copy(ptr-> array, ptr->array + 4, s->array); //copy array
delete[] s->array; //delete array, must use delete[]