First, there's almost no point in using malloc() in a C++ program. You can use:
int* array = new int[n];
...which is easier to type, and easier to read. Also, the array is an array of class-type objects, new will ensure that constructors are called for every array member, and the corresponding delete[] will call destructors. The malloc()/calloc() and free() functions won't do that.
The thing you can't do in C++ (yet?) is use a non-constant expression for the dimension of an array. So, you can't calculuate the size of the array, based on arguments or input values, and allocate just the right array size for your problem.
You need dynamic memory to do that in C++. (C added variable length arrays in 1999, but C++ never adopted that change.)
Dynamic memory also allows you to return a variable-sized result from a function. There are better ways to do this than with pointers and arrays, but think about how you would handle the following problem with what you know now:
Write a function that takes a string of comma-separated decimal numbers, and returns the median value of that list as an int. (i.e. the middle value in the list after sorting.)
You'll need an int array to sort the values, but you don't know how big to make that array until you count the commas in the input string. This is a case where a dynamic array will be useful, only allocating enough memory and never too much.