Reputation: 92
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.
Upvotes: 1
Views: 209
Reputation: 369
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.
Upvotes: 0
Reputation: 4433
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]);
Upvotes: 0
Reputation: 36
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.
Upvotes: 0
Reputation: 75545
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.
Upvotes: 1
Reputation: 9599
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.
Upvotes: 1