1 вариант:
void func(int ** &arr, int size) {
arr = new int * [size];
<...>
}
int main() {
int size = <...>;
int **arr;
func(arr, size);
}
2 вариант:
void func(int **arr, int size) {
<...>
}
int main() {
int size = <...>;
int **arr = new int * [size];
func(arr, size);
}
Объясните, пожалуйста, почему в первом варианте мы в функции выделяем память под массив и передаем arr по ссылке, а во втором варианте в main выделяем память и тогда уже не надо по ссылке в функцию передавать arr. Не понимаю, как тут работают указатели.
В первом случае мы объявляем переменную arr типа int **. Передаем ссылку на нее в функцию func и уже там присваиваем ей значение.
Во втором случае мы объявляем переменную arr типа int ** и сразу присваиваем ей значение — указатель на выделенную память.
Таким и образом, и первый и второй вариант код верный. Какой именно способ использовать зависит от ваших предпочтений и, собственно, решаемой этим кодом задачи.
…и тогда уже не надо по ссылке в функцию передавать arr…
В первом случае мы могли бы воспользоваться указателем, а не ссылкой:
void func(int ***arr, size_t size) {
*arr = new int * [size];
<...>
}
Однако никто не мешает вам и во втором случае передавать arr по ссылке.
Никто не мешает в первом случае тоже выделять память в main. Но вот во втором случае выделять память в func не получится.
Смотрите, совсем простой пример:
#include <iostream>
void foo(int x)
{
x = 1;
}
int main()
{
int y = 0;
foo(y);
std::cout << y << '\n';
}
Что напечатает этот код, 1? Нет, 0, потому что x и y - разные переменные. А если сделать void foo(int &x), тогда результат будет 1.
С указателями то же самое.
Если вы внутри void func(int **arr, int size) сделаете arr = new ..., то переменная int **arr в main не изменится, и из main вы никак не получите доступ к этой памяти.
Однако! Если вы меняете arr[i] или *arr, то эти изменения в любом случае будут видны снаружи функции. При передаче arr из main в void func(int **arr, int size), копируется только сам указатель, но не то, на что он указывает (т.е. копируется адрес, записанный в указателе). То есть изменения самого указателя не будут заметны снаружи функции, в отличие от изменений того, на что он указывает.
Продвижение своими сайтами как стратегия роста и независимости