C++ support the basic data structures that C does, such as simple arrays, but that does not mean it is encouraged to do so. In C++ you are generally better of not writing basic arrays, but instead using the std::vector
class, or similar data structure.
That being said, the question was an interview question, so even though this approach is discouraged, in general, let us look at the function, and the initialization and allocation of the array.
The first thing to notice is that the code does not compile. The main function holds a loop with a loop variable i
that is not declared. This is a minor thing, and we can quickly fix it. Compiler output:
prog.cpp: In function ‘int main()’:
prog.cpp:29:7: error: ‘i’ was not declared in this scope
for(i=0;i<7;i++)
^
Once we have fixed the compiler error we can run the code, but the compiler will still provide some warnings, which I strongly suggest you look at:
prog.cpp: In function ‘int* Append(int*, int*, int, int)’:
prog.cpp:8:9: warning: address of local variable ‘a’ returned [-Wreturn- local-addr]
int a[size1+size2],i;
^
The warning has all the information we need at this point. (I do know that at an interview you might not have access to a compiler to see these things, but they are helpful when you get home and wonder why you got the reply like you did).
The warning basically says that the funtion is returning the address of a local variable. The local variable is deallocated once it leaves scope, that is how the stack works. We push to the stack when we declare the variables, and once the scope the variable is declared in is left, we pop the variables from the scope (or rather the allocated memory from the variables).
So the local variable a
, is declared in the beginning of the function on the stack, and once the function returns, the address of this local variable is returned, but the memory the variable reserved is released.
So yes, this is related to heap and stack, in that elements on the stack are alive while the scope they are declared in, is alive, while elements on the heap are kept alive until they are explicitly told to no longer be alive (using delete
or free
).
When you are told that you need to allocate the array on the heap, you can do so using the new[]
operator:
int* a = new a[size1 + size2];
Remember that something that is allocated using new[]
must be deallocated using delete[]
. I do not agree with using malloc
but this might be some requirement for the code, that will at some point release the code with free
, at which point you have no choice but using malloc
.
Again I would personally not do either, I would use std::vector
instead, why worry about this, when it could be as simple as: std::vector<int> a
? As an interview question though, it was asked to test your core language understanding, and while it would be good to be able to answer how to allocate the array on the heap, it would show a bit more strength to be able to reflect upon the code, and recommend an alternative, and better, approach. Such as not using new
/malloc
.
Generally C++ returns values and parses parameters by value (when we are not using the by reference option). Which means that we return a copy of the value we return. This is how we are able to return simple integers, or doubles, or even std::string
(we ignore the move constructors, and how they work for simplicity), because we make a copy of them, and return. Actually we also make a copy of the variable a
and return that. So you may wonder, why it fails when we make a copy of a
. But as we have already established, from the compiler warning, the value we are actually returning, is the address of a
.
When we declare an array in C++ (or C), we are allocating an area in memory, that is large enough to hold the requested number of elements. The variable, will then be a pointer to the address of the first element. It is that address we are actually copying, and not the actual area that it points to. So the function will return a pointer to an area, that is no longer allocated. The local variable a
, is no longer alive, but the contents of a
is copied, and is returned by the function.
Java is higher level language than C++ and does allow you to manipulate memory in the same way. In Java everything that is not a primitive (int
, double
, ...) is kept on the heap. Java objects are freed when there are no longer any references to them.