7

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

这是结构:

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

先感谢您。

4

7 回答 7

8

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

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


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

于 2010-01-21T19:51:58.847 回答
3

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

于 2010-01-21T19:49:59.367 回答
3

您的方案将复制数组的地址。返回的“副本”tSprite将具有指向与传入数据相同的数据(在内存中)的指针。

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

于 2010-01-21T19:50:48.697 回答
2

如果您正在编写的是 C++,请记住 C++ 有new并且delete是有原因的。至于问题本身,这取决于您是要复制指针还是结构本身。如果是后者,您也需要复制它们!

于 2010-01-21T19:52:45.187 回答
1

即使您使用纯 C 语言,这也不是正确的复制方式。

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

这将导致诸如谁将释放分配给的内存之类的问题Vertext2 GLubyte

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

是的,这是正确的方法

于 2010-01-21T19:57:34.030 回答
1

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

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

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

于 2010-01-21T19:58:29.147 回答
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[]
于 2010-01-21T20:03:13.173 回答