The program you have posted is doing following (in the given sequence below):
- Declare/define a pointer in a function
- Allocate memory to that pointer in some other function and fill that memory with user input
- Print the content of that memory using another function
- Deallocate memory and exit
The part which is confusing you is 2.
I don't understand why ar in the input function is an int** and not an int* ....
If you want to allocate memory to a pointer (or want to change the pointer, like, e.g. making it point to some other memory or reallocating memory etc.) in some other function, you need access of that pointer in that function and you can get access if you have the address of that pointer.
And that's why here the address of ar
pointer is passed:
input(&ar, &n);
Pass address of ar
to input()
function and in the input function dereference that address (i.e. *ar
) will give the ar
pointer (declared/defined in main()
).
For better understanding, I am renaming the ar
parameter of input()
function to input_ar
:
void input(int *input_ar, int *n) {
.....
.....
When input()
function called from main()
function, the in-memory view would be something like this:
input_ar ar
+-----+ +-----+
| 200 | ----> | NULL|
+-----+ +-----+
[200 is address of ar pointer]
In input()
function, when you do:
*input_ar = (int*)malloc(*n * sizeof(int));
dereferencing input_ar
(i.e. *input_ar
) will give ar
:
input_ar *input_ar (ar) (newly allocated memory block)
+-----+ +-----+ +-----+
| 200 | ---------> | 300 | ----> | |
+-----+ +-----+ +-----+
[300 is address of the newly allocated memory block]
Hence, by dereferncing input_ar
, the pointer ar
can be changed in input()
.
I mean I try to replace int** ar with int* ar and delete the * in int* ar = NULL in the main function and there's no compile error.
Note that if you remove the *
from declaration of ar
in main()
then ar
will be a variable of type int
, that means, it will not be a pointer but a variable which can hold a int
type value. If you do this change in your program, you have to make changes in other places as well like, the way you are taking input from user in input()
function, respective changes in output()
function etc.
You have not shown the program with the changes that you have done after deleting *
from ar
declaration so, I will just talk about the ar
argument passed to input()
:
This is what you might have tried:
int ar;
input (&ar, &n);
and in input()
:
void input(int *ar, int *n) {
printf("Number of elements: ");
scanf("%d", n);
ar = (int*)malloc(*n * sizeof(int));
.....
Note that the ar
pointer parameter is a local variable of input()
function.
When input()
function is called from main()
function, the ar
will hold the address of ar
variable of main()
function.
If you want, you can make changes in the value of ar
variable using the pointer ar
in input()
function, e.g. - *ar = 9;
This will assign value 9
to variable ar
(of main()
). The in-memory view would be something like this
ar (of input()) ar (of main())
+-----+ +-----+
| 200 | -------------> | |
+-----+ +-----+
[200 is address of ar variable of main()]
But when you do
ar = (int*)malloc(*n * sizeof(int));
the ar
has lost the address of ar
variable of main()
function and newly allocted memory reference is assigned to pointer ar
of input()
, i.e.
ar (of input()) newly allocated memory block
+-----+ +-----+
| 400 | -------------> | |
+-----+ +-----+
[400 is address of the newly allocated memory block]
You can write/modify the contents in this memory but when returned from input()
, this memory reference will be lost because input()
is not returning anything and this will be a memory leak in your program.