C ++: Будет ли структура скопирована правильно?

StackOverflow https://stackoverflow.com/questions/2112318

  •  22-09-2019
  •  | 
  •  

Вопрос

У меня есть указатель на структуру, и мне нужно реализовать метод, который скопирует все содержимое памяти структуры. Вообще говоря, мне нужно выполнить глубокую копию структуры.

Вот структура:

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

Проблема в том, что я не уверен, что массивы «вершины» и «vertex_indices» будут скопированы должным образом. Что будет скопировано таким образом? Адрес массива или сам массив?

Должен ли я скопировать массивы после копирования структуры? Или этого достаточно, чтобы скопировать структуру?

Что-то вроде этого:

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

Заранее спасибо.

Это было полезно?

Решение

Как правило, никогда не используйте memcpy в C ++ в нормальном коде (это мощь Помощи в коде очень низкого уровня, например, на распределителях)1). Анкет Вместо этого создайте подходящий конструктор копирования и перегрузку operator = (оператор назначения), чтобы соответствовать ему (а также Деструктор - правило трех: «Если вы реализуете любой из конструкторов копирования, operator = и деструктор, ты должен реализовать все три).

Если вы не реализуете свои собственные версии конструктора копирования и оператора назначения, C ++ создаст для вас версии по умолчанию. Эти версии будут реализовать мелкую копию (очень похоже на то, что memcpy подойдет), т.е. в вашем случае содержимое массива будет нет Будь скопированы - только указатели.


1) Между прочим, то же самое касается malloc а также free. Анкет Не используйте их, вместо этого используйте new/new[] а также delete/delete[].

Другие советы

Это частично зависит от ваших требований. Если вы не копируете массивы, обе структуры будут указывать на один и тот же массив, что может быть или не быть проблемой.

Ваша схема скопирует адреса массивов. «Копия» tSprite Возвращенный будет иметь указатели на те же данные (в памяти), что и пропущенные в одном.

Если вам нужна настоящая глубокая копия, вам нужно скопировать массивы (и любых членов их элементов) вручную.

Если вы пишете C ++, то помните, что C ++ new а также delete по причине. Что касается самого вопроса, это зависит от того, хотите ли вы копировать указатели или сами структуры. Если последнее, вам тоже нужно их скопировать!

Это не правильный способ копировать, даже если вы работаете на простом C.

Указанный в другом ответе, вы получите два (или более) экземпляры структуры, указывающие на то же самое Vertext2 а также GLubyte экземпляр, который не рекомендуется.

Это приведет к таким проблемам, как, кто освободит память, выделяется на Vertext2 GLubyte

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

Да, это правильный способ сделать это

Сами указатели будут скопированы, но это означает, что оба «от» и «до» будут одинаковыми в двух спрайтах. Вам также необходимо вручную выделить и скопировать то, на которые указаны указатели, но это подразумевает, что вам также нужно знать, насколько велики массивы, на которые ссылаются указатели.

Обратите внимание, что вместо Memcpy там вы также можете сделать ' *pspriteToreturn = *copyFromme;' Это скопирует всех участников, хотя, если вы собираетесь сделать новые массивы, единственная часть Tsprites, которую вы хотите скопировать, - это размер.

Другое примечание заключается в том, что если у ваших спрайтов всегда есть фиксированное количество вершин и индексов Vert, вы можете сделать эти массивы внутри спрайта, а не указателей. Если вы сделали это, то они были бы правильно скопированы как с помощью метода MEMCPY, так и с заданием, которое я упоминаю в приведенном выше абзаце.

в 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[]
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top