Returning pointers in c

Thread Starter

andy24691

Joined Nov 25, 2010
42
This is my program, the part I'm having trouble with is in red:

#include<stdio.h>

int* cheese(void);

int main()

{
int n, freq[18], *pointer, i;

printf("Frequency \n");


for (n = 0; n < 18 ; n++)
{

if (n < 9)
freq[n] = (n+1)*100;

else
freq[n] = (n - 8)*1000;
}

for (n=0; n<18; n++)
{

printf("%4d \n", freq[n]);
}


pointer = cheese();

for(i=0; i<18; i++)
printf("%d \n", *(pointer + i));

return(0);

}



int* cheese(void)
{
int n, array[18];
for(n=0; n<17; n++)
{
array[n] = n;
}

return(array);
}




My issue is in the function "cheese" I have created an array of 18 integers. I want to return the pointer to the first element of the array back to the pointer variable "pointer" in main. I can print individual element values by returning a pointer but when it comes to printing out all 18 as a for loop it won't work. It prints out a list of random numbers instead. Seeing it can print out individual elements fine I don't see why it can't do the loop. Could anyone shed light on this?
 

LoganFife

Joined Feb 7, 2010
13
hi Andy, you should declare your array outside of your function, then pass a pointer, or the name of the array.
like this...

void cheese(int list[]);

int main(void){

int array[18],i;

cheese(array);

for(i = 0;i<18;i++){
printf("%d /n", array);
}

}

void cheese(int list[]){

do stuff to populate the array;

return 0; /* no need to return as its call by reference*/
}
 

someonesdad

Joined Jul 7, 2009
1,583
Please learn to use the {code}...{/code} markup (use square brackets, not curly), as it makes it easier to read code.

You're making one of the classic programming blunders -- returning a pointer to an object that was allocated on the stack, but no longer exists when the stack frame goes away (the behavior is undefined). Either give it static storage class, create it on the heap with malloc, make it a global, or pass it in using a reference ("pointer" to C folks) to a local variable in your main function.
 

lff

Joined May 18, 2011
1
Please learn to use the {code}...{/code} markup (use square brackets, not curly), as it makes it easier to read code.

You're making one of the classic programming blunders -- returning a pointer to an object that was allocated on the stack, but no longer exists when the stack frame goes away (the behavior is undefined). Either give it static storage class, create it on the heap with malloc, make it a global, or pass it in using a reference ("pointer" to C folks) to a local variable in your main function.
This explains it perfectly. You defined array[18] inside of the function "cheese". When the function is finished executing, all local variables to the function (array[18] for example) will no longer exist (function scope). So referencing the location in memory to where your array was gives undefined behavior (the random numbers you see). Follow someonesdad's advice on how to overcome this.
 

hgmjr

Joined Jan 28, 2005
9,027
Another solution would be to change the variable declarations in the function cheese to be static.

Rich (BB code):
static int array[18];
int n;
That should preserve the integrity of the array of values.

hgmjr
 

Thread Starter

andy24691

Joined Nov 25, 2010
42
Thanks for the responses, I have resolved the problem now. What you have said about the array dissappearing once the function has ended makes a lot of sense but I am curious to know why I was able to print off individual elements by returning pointers as by the same logic this should be undefined as well, wouldn't it?
 

someonesdad

Joined Jul 7, 2009
1,583
You need to learn what "undefined" means to a compiler writer... :p

The usual case is that the area of memory where the stack is allocated is not changed after the stack frame is destroyed (for efficiency -- why waste processor cycles on something "everyone" knows not to touch?). Thus, the changes you made to that memory will still be present. But, imagine if you had called another function, which would have created a completely different stack frame. Then the pointer you had wouldn't refer to anything sensible.

This is one of those programming errors that may not be taught forcibly and directly in the textbooks. The easiest thing for a writer to say is "don't return pointers to local variables". But an unsuspecting user won't (deeply) appreciate the reason for this. Often, you may not find out about it until a program starts misbehaving. Then you have to debug it and find the cause.

Fortunately, you learned the lesson in a trivial example and, hopefully, it's a lesson you'll remember. In C++ with complicated structures, references, etc., it can even happen that an experienced programmer can make this mistake -- and they can be hard to debug unless you get very familiar with your compiler and libraries, knowing the typical addresses of where things get allocated. In the good environments I've worked in, however, this would likely have been spotted in a simple code review.
 
Top