C : array1 = array2 против использования цикла для присвоения значений array2 array1

#c #arrays #pointers

#c #массивы #указатели

Вопрос:

Я ищу кого-нибудь, кто исправит мое понимание указателей и массивов.

Допустим, у меня есть два массива:

 int* array1 = new int[10];
int* array2 = new int[10]{ 1,2,3,4,5,6,7,8,9,10 };
  

Когда я это делаю array1 = array2 , я получаю следующие значения адресов:

 array1: 0000027964C831D0
array2: 0000027964C831D0
amp;array1[0]: 0000027964C831D0
amp;array2[0]: 0000027964C831D0
  

Когда я это делаю for (size_t i = 0; i < 10; i ) { array1[i] = array2[i]; } , я получаю:

 array1: 0000027964C832B0
array2: 0000027964C83710
amp;array1[0]: 0000027964C832B0
amp;array2[0]: 0000027964C83710
  

Первый случай (без цикла) имеет смысл для меня. Я присваиваю адрес массива в array2 array1, так что теперь у меня есть два разных указателя, указывающих на один и тот же массив (или, точнее, array2[0] ), следовательно, amp;array1[0] и amp;array2[0] одинаковы.

Но во втором случае (цикл) с самого начала указатели имеют разные адреса. Правильно ли я говорю, что цикл for создал копию массива? Хотя для меня это звучит неправильно.

Комментарии:

1. Цикл копировал значения из одного массива в другой. У вас уже было 2 массива для начала (из-за new int[10]; инициализации)

2. @UnholySheep Спасибо за комментарий. Вот что я тогда понимаю. В первом случае array1 указывает на array2, и если я не удалю перед выполнением array1 = array2, произойдет утечка памяти. Во втором случае все значения array2 просто копируются в array1. Так что, даже если я не удаляю перед циклом, утечки памяти нет?

3. В первом случае array1 и array2 являются указателями. Во втором случае вы активно копируете по значению. Редактировать: удалено ненужное использование «по существу»

4. @Aditya Не только «по существу» — они являются указателями.

5. @molbdnilo ненужное использование слов было плохой привычкой для me…my плохой лол

Ответ №1:

Указатели — это адреса. Думайте о них как о листках бумаги с написанным на них домашним адресом.

 int* array = new int[10];
  

строит строку из 10 домов ( new int[10] ), затем записывает, где находятся эти дома, и сохраняет адрес array .

Сказать array , что это массив, — это проблема, которая вас смутит. Он ошибочно принимает адрес дома за дом. Лист бумаги с надписью 123 road street «это не мой дом», даже если он однозначно называет мой дом.

Ошибочно принять карту за территорию действительно легко и приводит к путанице. Вам нужно проделать некоторую работу, чтобы распутать это.

array1=array2 берет листок бумаги array1 и записывает на нем адрес 2-го блока домов. Он ничего не делает с домами. Они все еще существуют, но у вас может больше не быть записи о том, где они находятся. Так что теперь они станут заброшенными и потерянными (это называется утечкой памяти).

array1[0] = array2[0] берем вызванный лист бумаги array2 , идем по указанному на нем адресу и смотрим на первый дом там (он же 0 ). Затем он вытаскивает сканер и сканирует весь дом.

Затем вы переходите к месту array1 , где говорится, что есть ряд домов. Вы идете в первый дом (он же 0 ) и вытаскиваете свой сканер. Вы переключаете переключатель с сканирования на печать и нацеливаете его на дом.

Он продолжает уничтожать находящийся там дом и распечатывает копию дома, который вы отсканировали, в блоке с именем by array2 .

Затем вы возвращаетесь к блоку с именем by array2 , сканируете array2[1] 2-й дом в блоке, возвращаетесь и печатаете его поверх array1[1] второго дома в первом блоке.

Это совсем, совсем другая операция, чем царапать адрес блока на листе бумаги и заменять его.

Теперь amp;array1[0] переходим к блоку с именем by array1 , переходим к первому дому [0] , затем читаем адрес, написанный на нем ( amp; ) . Поскольку мы называем блоки по адресу первого дома, получается, что это соответствует тому, что мы записали в array1 себе.

array1[1] будет иметь другой адрес — amp;array1[0] — но он будет по соседству array1[0] .