Необходимо различать указатель на массив и элементы этого массива.Давайте сначала пройдемся по тому, что вы делаете прямо сейчас:
int main(void)
{
int *arr, n;
scanf("%d", &n);
arr = (int*)malloc(n*sizeof(int));
// ...
func1(arr, n);
}
int *arr
объявляет указатель на int
в области действия функции main()
.Через какой-то указатель вы передаете этот указатель в функцию func1
.Теперь C является языком передачи по значению, это означает, что func1
получает значение arr
, и это значение является адресом вашего динамически распределяемого массива.Это позволяет вам манипулировать элементами, на которые указывает arr
, но не самим arr
.Так что если внутри func1
у вас есть:
void func1(int *arr, int n) {
arr = dynamic_pointer_to_another_array();
}
, то изменится только arr
внутри func1
, но не тот, что в main
.Теперь вы частично это поняли, потому что ваша change()
функция вместо этого принимает указатель на указатель, однако в func1()
вы имеете:
change(&arr, h, i);
Вы можете подумать, что &
здесь передаетадрес arr
из main
, но на самом деле он передает адрес arr
из func1
, потому что еще раз C является передачей по значению языка.Каждый раз, когда вы передаете значение функции, оно копируется в область действия этой функции, и любые операции над значением не будут отражаться в вызывающей стороне.
Простое решение этого - изменить func1
навозьмите int **arr
вместо int *arr
, таким образом, вы можете сделать:
change(arr, h, 1);
и внутри change
вы можете сделать:
*arr = new_array();
Это будет работать, потому что тогдавы передаете адрес указателя вместо самого указателя, и через адрес указателя вы можете изменить то, на что указывает указатель.
Важное примечание
В вашем коде есть еще один огромныйпроблема.Вы динамически выделяете массив, а затем пытаетесь переназначить указатель на этот массив другому массиву.Это, безусловно, приведет к утечкам памяти и висящим указателям.Выполнение
int *arr = malloc(sizeof(int) * N);
arr = new_array();
гарантированно приведет к утечкам памяти, поскольку вы никогда не используете free
для этого указателя для освобождения памяти, а после переназначения ее другому массиву вы теряете все ссылки на него.У вас есть несколько вариантов, как это сделать.Если вам нужно увеличить размер arr
, тогда вы используете realloc
вместо выделения нового массива.Таким образом, вам все равно придется только free
один раз.