Returning pointers in c

Discussion in 'Programmer's Corner' started by andy24691, May 19, 2011.

  1. andy24691

    Thread Starter Member

    Nov 25, 2010
    42
    0
    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?
     
  2. LoganFife

    New Member

    Feb 7, 2010
    13
    0
    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*/
    }
     
  3. someonesdad

    Senior Member

    Jul 7, 2009
    1,585
    141
    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.
     
  4. lff

    New Member

    May 18, 2011
    1
    0
    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.
     
  5. hgmjr

    Moderator

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

    Code ( (Unknown Language)):
    1.  
    2. static int array[18];
    3. int n;
    4.  
    That should preserve the integrity of the array of values.

    hgmjr
     
  6. andy24691

    Thread Starter Member

    Nov 25, 2010
    42
    0
    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?
     
  7. someonesdad

    Senior Member

    Jul 7, 2009
    1,585
    141
    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.
     
    lff likes this.
Loading...