1

I'm extremely new to C programming, and am going through some tutorials. One thing that stumped me is with returning a pointer to an array. I've cut down the example from https://www.tutorialspoint.com/cprogramming/c_return_arrays_from_function.htm to best illustrate my point.

#include <stdio.h>

int * getRandom( ) {

   static int  r[10];
   int i;

   for ( i = 0; i < 10; ++i) {
      r[i] = i;
      printf( "r[%d] = %d\n", i, r[i]);
   }
   return r;
}

int main () {
   int *p;
   int i;
   p = getRandom();
   for ( i = 0; i < 10; i++ ) {
      printf( "*(p + %d) : %d\n", i, *(p + i));
   }
   return 0;
}

As one would expect, this prints

r[0] = 0
r[1] = 1
r[2] = 2
r[3] = 3
r[4] = 4
r[5] = 5
r[6] = 6
r[7] = 7
r[8] = 8
r[9] = 9
*(p + 0) : 0
*(p + 1) : 1
*(p + 2) : 2
*(p + 3) : 3
*(p + 4) : 4
*(p + 5) : 5
*(p + 6) : 6
*(p + 7) : 7
*(p + 8) : 8
*(p + 9) : 9

But when you change

   static int  r[10];

to

   int  r[10];

it instead prints

r[0] = 0
r[1] = 1
r[2] = 2
r[3] = 3
r[4] = 4
r[5] = 5
r[6] = 6
r[7] = 7
r[8] = 8
r[9] = 9
*(p + 0) : 0
*(p + 1) : 1980517315
*(p + 2) : -1164399724
*(p + 3) : 4199040
*(p + 4) : 4199040
*(p + 5) : 2285568
*(p + 6) : 19
*(p + 7) : 6356668
*(p + 8) : 8
*(p + 9) : 6356940

and I have no idea why. The only thing I can think of is that for some reason the compiler is reading the array cells as different data types, but I doubt that's right.

2
  • 1
    read your compiler warnings: returning reference to temporary is not good. It means that values will be overwritten anytime (hence the static keyword). Cannot find the duplicate for this. Commented Oct 16, 2016 at 22:39
  • Thanks for all the responses; I think I understand this now. So essentially, once you leave the getRandom function the memory used for the rest of the array is reassigned, but this can be bypassed with 'malloc()' which assigns stack memory for the function output. Commented Oct 17, 2016 at 17:10

5 Answers 5

1

The static keyword is used to "remember" the value of r in the next call. If you remove it, then the memory allocated for r is flushed when the function returns, so you're just returning garbage.

Sign up to request clarification or add additional context in comments.

Comments

1

When you have static int r[10];, the memory for storing the array is allocated at compile-time, and everything works as expected.

When you instead have int r[10], you are allocating your array on the run-time stack frame, which becomes invalid when the function call returns, and then gets overwritten by the next function call, so you see garbage.

Comments

0

The reason is that when you call getRandom() without a static array declaration, the array falls out-of-scope once the getRandom() function returns. This means that your pointer may no longer 'point' to r, because r is essentially discarded.

In order to return from getRandom() correctly, you would need to dynamically allocate your memory using malloc, for example:

int * getRandom( ) {
  int *r = NULL;
  r = malloc(sizeof(int) * 10); /* Create room for 10 integers*/
  if (r == NULL) {
    printf("Error: Could not allocate space\n");
    return NULL;
  }
  int i;
  for ( i = 0; i < 10; ++i) {
    r[i] = i;
    printf( "r[%d] = %d\n", i, r[i]);
  }  
  return r; /* Returns a pointer to r*/
}

int main () {
  int *p;
  int i;
   p = getRandom();
   if (p == NULL) {
     /*Error state*/
     return 1;
   }
   for ( i = 0; i < 10; i++ ) {
     printf( "*(p + %d) : %d\n", i, *(p + i));
   }
   free(p); /* Free the memory we allocated*/
  return 0;
}

Note how we must free the memory we allocated (otherwise we would have memory leaks). Also note that we must handle the NULL case, where we could not allocate the memory necessary.

Comments

0

Excepting by a few cases, an array in a expression always decays to the address of its first element.
This pointer is the value returned by the function.
The array itself, as an object living in memory, in general dies after the function execution finished.
So, the memory address pointed by the pointer that the function returned is not guaranteed to preserve the array, and it could have garbage instead.
The static declaration preserves the array object, but still your function have returned a pointer to the head of the array and not the array itself.
It is bad practice to return a pointer to an inner static object of a function, because you are allowing to any user of your function to change the values of the array from outside of the function in umpredictable ways.
If you want to return a complete array, as a value, perhaps you should define a struct type containing an array field, in this way:

  typedef struct {  int sub[10]; } wrappedarray_t;
  wrappedarray_t getRandom(void) {
         wrappedarray_t r;
         // sentences....
         return r;
   }
   wrappedarray_t p = getRandom();
   printf("0th element: %d\n", p.sub[0]);

Comments

0

because you're using a locally allocated piece of data; once the program goes out of scope, then all the data you saved to it is thrown out and it'll return garbage values.

In this situation, you can do two things:

either malloc() a pointer-array OR use the static array and return one of them.

ANOTHER option you can do is to put an array buffer in the function parameters so the data is copied to that buffer.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.