Это хорошая практика для копирования объектов из стека в кучу, установив указатель с разыменованным? - PullRequest
1 голос
/ 01 апреля 2020

Пожалуйста, рассмотрите этот пример программы:

#include <stdio.h>
#include <stdlib.h>

typedef struct {
  int a;
  int b;
} X;

int main(void) {
  X* p = malloc(sizeof(X)); // Heap allocation
  X z = {.a = 2, .b = 3}; // Stack allocation
  *p = z; // Copying from the stack onto the heap

  printf("\n%d\n", p->b);

  return 0;
}

Эта программа правильно печатает 3. Я предполагаю, что это означает, что *p = z успешно скопировал данные z из стека в кучу.

Если это так легко скопировать вещи из стека в кучу, почему большинство людей используют memcpy при попытке сделать это? (например, этот вопрос SO) .

В каких ситуациях memcpy уместно, а в каких ситуациях вышеприведенное решение хорошо?

Ответы [ 2 ]

1 голос
/ 01 апреля 2020

«Рекомендуется ли копировать объекты из стека в кучу, устанавливая указатель с разыменованным?»

Да. *p = z; это хорошо. Преимущество перед memcpy(): проверка типов.

В каких ситуациях подходит memcpy, в сравнении с какими ситуациями подходит вышеуказанное решение?

  • memcpy: при копировании массива

  • memcpy: когда источник / место назначения не выровнены (код должен упаковать / распаковать данные).

  • Остальное: используйте просто присваивание.

1 голос
/ 01 апреля 2020

Вы будете использовать memcpy, когда копируете содержимое одного массива в другой (и это содержимое не составляет строку ), или когда вы пытаетесь отобразить содержимое объект одного типа на байты объекта другого типа.

Например, если вы отображаете свой тип struct на массив unsigned char, вы должны сделать что-то вроде:

X foo = {1, 2};
unsigned char *bytes = malloc( sizeof foo );
unsigned char sbytes[sizeof foo];

memcpy( bytes, &foo, sizeof foo );
memcpy( sbytes, &foo, sizeof foo );

Аналогично, если вы пытаетесь скопировать содержимое одного массива в другой, и это содержимое не составляет строку , вы также должны использовать memcpy:

int src[N];
int *dst = malloc( sizeof src );
int sdst[N];
...
memcpy( dst, src, sizeof src );
memcpy( sdst, src, sizeof src );

Если они составляют строку, вы бы использовали strcpy:

char blah[10];
strcpy( blah, "foo" );

В противном случае используйте оператор присваивания, как вы сделали здесь.

...