Not related to the question, but the name STL has been deprecated for years, the correct name is Standard C++ library.
Next for how objects are passed to functions, you should be aware that arrays are not first class elements in C++. Since C++ 11 (draft n3337):
Array-to-pointer conversion [conv.array]
An lvalue or rvalue of type “array of N T” or “array of unknown bound of T” can be converted to a prvalue
of type “pointer to T”. The result is a pointer to the first element of the array.
So when you try to pass an array to a function, it decays (recursively if multi-dimensional) to a pointer to its first element. Then that pointer is passed (by value) which is almost equivalent of a pass by reference call of the array.
But all other objects are passed by value, be them custom objects or object from the standard library.
For the stack vs. heap question, it is unrelated to the standard, because C++ has no notion of head and stack, but only automatic vs. dynamic variables. Simply common implementations use the stack for automatic variables and the heap for dynamic memory.
Let's go on one step further:
void f() {
double arr_auto[1000]; // automatic array (stack on common implementations)
// will be automatically destroyed at end of block
double* arr_heap = new int[1000]; // dynamically allocated array
// will require an explicit delete[]
std::vector<int> vec(1000); // vec is an automatic object (stack),
// hosting a dynamic array of 1000 doubles
// everything (vector and content) will be destroyed at end of block
g1(arr_auto); // actually passes &(arr_auto[0]) a mere pointer to an automatic array
g1(arr_heap); // equally passes a pointer but to a dynamically allocated array
g2(vec); // assuming g2 is declared g2(vector<int>& v) passes a reference
g3(vec); // assuming g3 is declared g3(vector<int> v) constructs a copy of vec
...
}
For the last case (pass an object by value), an automatic copy of the object is constructed via the copy constructor. And containers from the standard library do allocate dynamic memory for their content - and their destructor ensure that the dynamic memory is freed when their life time ends. So you get a full copy of the original values allocated in dynamic memory (heap for common implementations), without needing to care for explicit deletion.
Hope it is more clear now...