Basically the exercise says “Create a function which takes as an argument an array and its size and returns a new array with contains the three biggest values of the array given as the argument.” So I thought that I will take the array and sort it in the function and then give the 3 highest values to a new array and return it. That’s my code.
int *function(int *A, int k){
int B[3],i,j,temp;
//Sorting
for(i=k-1;i>0;i--){
for(j=1;j<=i;j++){
if(A[j-1] > A[j])
{
temp = A[j-1];
A[j-1] = A[j];
A[j] = temp;
}
}
}
i = 0;
while(i < 3){
B[i]= A[k-1];
i++;
k--;
}
return B;
}
int main (int argc, const char * argv[]) {
int A[5] = {1,8,7,4,6};
int size = 5;
int *func,i;
func = function(A,size);
for(i=0;i<3;i++)
printf("%d ",func[i]);
return 0;
}
As a result I should get 8 7 6 but I’m getting 8 -1073743756 6. I can’t find the mistake. I also get a warning when I want to return B. It says “Function return address of local variable.” Maybe this has something to do with this problem. Any ideas?
The ‘lifetime’ of the variable B is for the duration of the function in which it is declared. When it is out of scope it no longer exists, and its memory may be reused for other purposes. You should regard all compiler warnings as errors – they are usually semantic errors (as opposed to syntax errors); that is to say, the compiler understands the code, but it is unlikely that it is what you intended, or may have unintended or undefined behaviour.
In this case the compiler is telling you exactly what the problem is. What you need to be asking perhaps is how best to resolve the error.
The normal pattern to use when a caller requires an array to be filled by a function is for the caller to provide the array to the function. Because arrays ‘decay’ to pointers when passed to a function, it is normal to also pass the length, and this is useful to avoid buffer overrun. You could have the function “know” that the buffer length is always 3 in your case, but it is less maintainable and less safe.
Typically such a function returns a pointer to the caller’s buffer, or NULL on failure, so it can be used for error checking or for use as the argument to another function.
Example:
then
It is possible to resolve the problem by either allocating B statically, globally, or dynamically. All these solutions I would class as “quick-and-dirty”. They may resolve this particular problem, but are not a general pattern that scales well to more complex and larger applications.
Dynamic memory allocation locally within
function()begs the question of who is then responsible to freeing the memory allocated?Local static allocation works, but if you call the function a second time the previous data will be lost, which may not always be acceptable. It is also not reentarnt, causing potential problems in a multi-threaded application, or recursive algorithms.
Global data is statically allocated but as the additional problem of being globally visible, so no longer under the sole control of the one function.