int* sumArrays(int* a, int* b, int N){ int* c = new int[N]; for (int i = 0; i < N; ++i) c[i] = a[i] + b[i]; return c; }Does this code compile and run? Explain its errors or disadvantages and give a correct or improved solution.
The code compiles and runs, but it is very dangerous. It allocates memory but does not deallocate it. It transfers the responsibility for the deallocation to the caller. If the caller accepts that responsibility and remembers to deallocate when done with it, then the code works. The problem is that it is very unlikely that the caller will in fact always remember to deallocate when done. Forgetting one time is enough to cause a memory leak which might not be detected during testing.
C++ does not allow arrays to be returned (e.g., int[] cannot be the return type). It does allow pointers to be returned, but for the pointer to be useful, it must hold the address of some object that will persist in memory after the function's local variables are reclaimed. I.e., it cannot hold the address of one of the function's local stack (auto) variables. Because arrays cannot be returned from functions, and because of other differences in the syntax associated with them, they are not "first-class" objects.
The easiest and cleanest solution is to use a wrapper class for the array. By making the array a member of an object of a user-defined type, the array becomes part of a first-class object, which can be copied (e.g., by the assignment operator =) and returned from a function in the usual way. E.g.,
struct myVec{ enum {MAX = 100}; int array[MAX]; int length}; myVec sumVecs(const myVec& a, const myVec& b){ myVec c = a; // all members automatically copied, correctly. assert (c.length = b.length); for (int i = 0; i < N; ++i) c[i] += b[i]; return c; }
Note, however, that the array member of this class has fixed length. Managing array members of dynamically specified lengths requires correct implementation of the default constructor, copy constructor, destructor, and assignment operator. If the arrays must have dynamically specified lengths, then it is best to use a library type, e.g., vector<int>. Savitch has a gentle introduction. The vector<int> is especially useful, because the sizing and resizing will be done automatically, as with std::strings.
For further discussion of the kinds of memory used by your program, see the online handout.