Задать вопрос
@AslanPAPA

Почему при передаче указателя в функцию, функция получает копию?

Привет!
int input(int *arr, int *n) {
    if (scanf("%d", n) != 1) return -1;
    arr = (int*)malloc(sizeof(*arr) * *n);
    if (arr == NULL) return -1;

    for (int i = 0; i < *n; ++i) {
        if (scanf("%d", arr[i]) != 1) return -1;
    }

    return 0;
}

int main(void) {
    int *arr = NULL;
    int n = 0;

    input(arr, &n);


тут я вроде бы передал arr в input, и должен работать не с её копией, а с этим же адресом. А в итоге идя возвращаясь обратно в функцию main я получаю старые значения, который и не менялись в функции. Или я тут передал в функцию не адрес, а значение указатлея arr т.е NULL? Если это так то я запутался т.к с передачами массива же все хорошо, передал к примеру из main массив arr[4] = {1,2,3,4}; и в функци передал его просто как arr и работай с началом адреса. Не понимаю почему при примере выше ни так. Ну если передать адрес в input(&arr) то тогда в input(**arr) и что мы там будет работать с адресом arr и в malloc на выделенную память будет указывать не arr, а *arr т.е адрес нашего переданного указателя ? Но опять же путаюсь почему arr не адрес, ведь при передаче массива это адрес?
  • Вопрос задан
  • 223 просмотра
Подписаться 1 Средний Комментировать
Помогут разобраться в теме Все курсы
  • Нетология
    Разработчик на C++
    12 месяцев
    Далее
  • Яндекс Практикум
    Разработчик C++
    9 месяцев
    Далее
  • Академия Эдюсон
    Разработчик игр на Unreal Engine + ИИ
    9 месяцев
    Далее
Пригласить эксперта
Ответы на вопрос 4
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
arr = (int*)malloc(sizeof(*arr) * *n);Здесь вы меняете значение переменной arr, но это изменённое значение не выйдет за пределы функции. Нужно передавать в функцию ссылку на переменную и изменять значение по этой ссылке. То, что переменная arr сама является ссылкой ничего принципиально не меняет.
int input(int **arr, int *n) {
    if (scanf("%d", n) != 1) return -1;
    *arr = (int*)malloc(sizeof(int) * *n);
    if (*arr == NULL) return -1;

    for (int i = 0; i < *n; ++i) {
        if (scanf("%d", (*arr)[i]) != 1) return -1;
    }

    return 0;
}

int main(void) {
    int *arr = NULL;
    int n = 0;

    input(&arr, &n);
Ответ написан
Комментировать
opium
@opium
Просто люблю качественно работать
Тут ключевой момент: arr[i] = что-то и arr = malloc() — принципиально разные операции. Первое меняет данные по адресу (туда, куда указатель смотрит), это видно из main. Второе меняет сам указатель, а он в функции — локальная копия.

Поэтому int **arr и *arr = malloc() — передаёшь адрес самого указателя и меняешь его через разыменование.
Ответ написан
@rPman
рекомендация, при определении типа, если цель - передача по ссылке, использовать
int input(int &*arr, int &n)
и пользоваться как обычной переменной
arr=(int*)malloc(...)

еще совет, не пользоваться malloc а new int[size] и соответственно потом delete
Ответ написан
wataru
@wataru
Разработчик на С++, экс-олимпиадник.
input(int *arr, - тут вы передали в функцию указатель. Адресс.
arr = (int*)malloc(sizeof(*arr) * *n); тут вы перезаписали это значение на новое.

Массив - это указатель, адрес. Представьте что это число - сколько байт от начала памяти надо отсчитать, чтобы найти начало массива.
Понятно, почему в этой программе не меняется значение arr?
void input(int arr) {
  arr = 10;
}

int main() {
 int x = 0;
 input(x);
 return 0;
}


Вот и у вас так же. int *arr - указатель на int. * говорит, что это ардес, по которому лежит что-то. В данном случае int. ТЕсли вы хотите вернуть значение из функции, вам надо одно из:
1) Возвращать int* из функции.
2) Передавать указатель на указатель int **arr в аргументах функции. Тогда вы сможете из функции менять массив int *
3) Передавать указатель по ссылке. Но это выглядит криво и так обычно не делают.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы