#arrays #c #dynamic #malloc #memcpy
#массивы #c #динамический #malloc #memcpy
Вопрос:
Я был бы очень признателен за некоторые объяснения, почему я неправильно использую memcpy, т. Е. Почему вывод следующего кода неправильный:
int main()
{
int array[5] = {1, 2, 3, 4, 5};
int *ptr = malloc(sizeof(int) * 5);
memcpy(ptr, array, 5);
printf("%dn", ptr[0] );
printf("%dn", ptr[1] );
printf("%dn", ptr[2] );
printf("%dn", ptr[3] );
printf("%dn", ptr[4] );
free(ptr);
return 0;
}
результат такой: 1 2 0 0 0
Комментарии:
1. Такого рода проблемы могут быть тривиально решены за несколько секунд, если заранее изучить, как работает функция, прежде чем использовать ее, а не программировать с помощью «рискнуть», за которым следует метод проб и ошибок.
2. Вы правы в том, что определили использование
memcpy
в качестве виновника. Он долженmemcpy(ptr, array, 5*sizeof(int));
//копировать все 20 байтarray
, а не только 5.3. Если коду необходимо сделать копию
array
, упростите выделение до размераarray
:int *ptr = malloc(sizeof array);
Ответ №1:
3-й аргумент memcpy()
— это количество байтов для копирования, а не количество элементов.
В этом случае,
memcpy(ptr, array, 5);
должно быть
memcpy(ptr, array, sizeof(int) * 5);
или
memcpy(ptr, array, sizeof(*ptr) * 5);
или
/* copy the whole array, no *5 in this case */
memcpy(ptr, array, sizeof(array));
Комментарии:
1. UV для простоты
memcpy(ptr, array, sizeof array);
. Пропустите эту ненужную5
часть.
Ответ №2:
Это плохо, потому что у вас есть массив из 5, int
но у вас memcpy
5 байт. malloc
и memcpy
работают одинаково, они ожидают количество байтов в качестве входных данных. Итак, почему вы даете одну из них sizeof(int) * 5
, а другую 5
?
Комментарии:
1. Большое спасибо. Я пропустил эту маленькую деталь.
2. @WojciechMierzejewski — Вы можете принять этот ответ, нажав на пустую галочку. Это действительно лучший способ сказать спасибо на этом сайте 🙂
Ответ №3:
почему я неправильно использую memcpy, т. Е. Почему вывод следующего кода неправильный
memcpy() Копирует указанное количество байтов из исходного буфера в целевой буфер.
Утверждение:
int *ptr = malloc(sizeof(int) * 5);
Создает указатель на память с пространством для 5 целых чисел, (т.е. 5*sizeof(int)
)
Аналогично, утверждение:
int array[5] = {1, 2, 3, 4, 5};
Создает int
array
с пробелом для 5
int
. (опять же — 5*sizeof(int)
) Но ваше memcpy()
утверждение копирует только часть array
:
memcpy(ptr, array, 5);
Иллюстрация: Предполагая, что sizeof(int) == 4
следующее показывает, какая часть array
копируется:
|0001|0002|0003|0004|0005|
|---- -| first 5 bytes
Таким образом, копируются только первые 5 байт array
, в то время как для этого необходимо скопировать все 5*sizeof(int) == 20
байты. Измените инструкцию на:
memcpy(ptr, array, 5*sizeof(int));
Ответ №4:
что касается;
memcpy(ptr, array, 5);
Это копирует 5 байт, куда вы хотите скопировать 5 целых чисел. Предлагаю;
memcpy(ptr, array, 5*sizeof(int) );