C динамический массив правильных цифр

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