problem returning pointer from function 
Author Message
 problem returning pointer from function

I think that this should work, but it doesn't.  Inside the function,
*(new_deck + i) prints just fine.

Back in main, I only get:

1
1
1
1
2
2
2
2
3
3
3
3
4
4
4
4
872415237
0
1
1244787
0
0
4207541
0
2012894640
2012660170
2147348480
4262560
1244872
4199215
0
4262560

Here's the code: both solutions and general critique are welcome.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAXCARDS 40

int * shuffle_cards(void);

int main(int argc, char * argv[])
{
        int deck[MAXCARDS];
        int * deck_ptr;
        int i;

        deck_ptr = malloc(sizeof(deck[MAXCARDS]));

        deck_ptr = shuffle_cards();

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

        return (0);

Quote:
}

int * shuffle_cards(void)
{
        int i;
        int * new_deck;
        int deck[MAXCARDS] = {
                1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,
                6,6,6,6,7,7,7,7,8,8,8,8,9,9,9,9,10,10,10,10
        };

        new_deck = deck;

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

        return new_deck;

Quote:
}

Please remove obvious characters from my e-mail address when e-mailing me.


Sun, 01 Jul 2001 03:00:00 GMT  
 problem returning pointer from function

You have misunderstood pointers and the scope of variables. See my
comments throughout the code. Email me if you have any further
questions.

To illustrate my point, move the integer array "deck" before main and
make it global. This will now work. This illustrates the "local scope"
of the integer array "deck". BUT stay away from global variiables.
Keep everything as local as possible. Pass pointers, return values...

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAXCARDS 40

int * shuffle_cards(void);

int main(int argc, char * argv[])
{

        int deck[MAXCARDS];   // not used!
        int * deck_ptr;
        int i;

        // correct! you have allocated memory correctly - you never
        // use this block of memory however!!!
        deck_ptr = malloc(sizeof(deck[MAXCARDS]));

        // with the following statement you've overridden the above
        // memory pointer
        deck_ptr = shuffle_cards();

        // you are now trying to print an integer array that has
        // been deallocated from the stack!!! The "garbage" you see
        // are other variables overwriting the integer array "deck"
        for (i = 0; i < MAXCARDS; i++)
                printf("%d\n", *(deck_ptr + i));

        return (0);

Quote:
}

int * shuffle_cards(void)
{
        int i;
        int * new_deck;
        int deck[MAXCARDS] = {
                1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,
                6,6,6,6,7,7,7,7,8,8,8,8,9,9,9,9,10,10,10,10
        };

        new_deck = deck;

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

        // you cannot return new_deck like this.
        // new_deck points to the integer array "deck" which is
        // deallocated when the function returns. The variable scope
        // of "deck" is limited to this function!!
        return new_deck;

Quote:
}



Sun, 01 Jul 2001 03:00:00 GMT  
 problem returning pointer from function

Quote:

>I think that this should work, but it doesn't.  Inside the function,
>*(new_deck + i) prints just fine.

[snip]
Quote:

>Here's the code: both solutions and general critique are welcome.

>#include <stdio.h>
>#include <stdlib.h>
>#include <string.h>

>#define MAXCARDS 40

>int * shuffle_cards(void);

>int main(int argc, char * argv[])
>{
> int deck[MAXCARDS];
> int * deck_ptr;
> int i;

> deck_ptr = malloc(sizeof(deck[MAXCARDS]));

> deck_ptr = shuffle_cards();

> for (i = 0; i < MAXCARDS; i++)
> printf("%d\n", *(deck_ptr + i));

> return (0);
>}

>int * shuffle_cards(void)
>{
> int i;
> int * new_deck;
> int deck[MAXCARDS] = {
> 1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,
> 6,6,6,6,7,7,7,7,8,8,8,8,9,9,9,9,10,10,10,10
> };

> new_deck = deck;

> for (i = 0; i < MAXCARDS; i++)
> printf("%d\n", *(new_deck + i));

> return new_deck;   ===>    The variable deck is local to the

shuffle_cards() routine !
                             It is allocated on the stack when the routine
is called and removed
                             when the routine returns !

Quote:
>}

Bye


Sun, 01 Jul 2001 03:00:00 GMT  
 problem returning pointer from function

Quote:

>         // correct! you have allocated memory correctly - you never
>         // use this block of memory however!!!
>         deck_ptr = malloc(sizeof(deck[MAXCARDS]));

This might indeed allocate memory, but certainly not the correct
amount. "deck[MAXCARDS]" represents one integer, and a nonexistant
one at that. Thus if the allocation succeeds it will have allocated
memory for exactly one integer.

And one more remark: never forget to check the return value of
"malloc()" !

Quote:
>         // with the following statement you've overridden the above
>         // memory pointer
>         deck_ptr = shuffle_cards();

Exactly. Something like: "shuffle_cards( deck );" would be more
apropriate, for an initialised "deck" of cards.

Quote:
>         // you are now trying to print an integer array that has
>         // been deallocated from the stack!!! The "garbage" you see
>         // are other variables overwriting the integer array "deck"
>         for (i = 0; i < MAXCARDS; i++)
>                 printf("%d\n", *(deck_ptr + i));

The resulting output is in fact an incarnation of Undefined Behaviour.
The code might as well crash the program or cause Stanford Wallace to
fly out of your ears.

Quote:
>         return (0);
> }

> int * shuffle_cards(void)
> {
>         int i;
>         int * new_deck;
>         int deck[MAXCARDS] = {
>                 1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,
>                 6,6,6,6,7,7,7,7,8,8,8,8,9,9,9,9,10,10,10,10
>         };

>         new_deck = deck;

I do wonder what this statement is meant to achieve. It sets the pointer
"new_deck" to point to the local variable "deck", but why ?

Quote:
>         for (i = 0; i < MAXCARDS; i++)
>                 printf("%d\n", *(new_deck + i));

>         // you cannot return new_deck like this.
>         // new_deck points to the integer array "deck" which is
>         // deallocated when the function returns. The variable scope
>         // of "deck" is limited to this function!!
>         return new_deck;
> }

Here's a version that might give the original poster a starting point.
It will not shuffle anything, but it will do what his code was very
likely meant to do, ie. overwrite the array in main with new contents.

 void shuffle_cards( int *deck )
 {
    int i;
    int new_deck[MAXCARDS] = {
                 1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,
                 6,6,6,6,7,7,7,7,8,8,8,8,9,9,9,9,10,10,10,10
         };

       /* This overwrites the original deck with the new deck. */
    for ( i=0 ; i < MAXCARDS ; i++ )
       deck[i] = new_deck[i];
 }

Stephan
(initiator of the campaign against grumpiness in c.l.c)



Sun, 01 Jul 2001 03:00:00 GMT  
 problem returning pointer from function
much good advice here -- just one more thing:
don't forget to free your allocations.  not all OSs will clean this up for
you.
-spence
Quote:

> I think that this should work, but it doesn't.  Inside the function,
> *(new_deck + i) prints just fine.

> Back in main, I only get:

> 1
> 1
> 1
> 1
> 2
> 2
> 2
> 2
> 3
> 3
> 3
> 3
> 4
> 4
> 4
> 4
> 872415237
> 0
> 1
> 1244787
> 0
> 0
> 4207541
> 0
> 2012894640
> 2012660170
> 2147348480
> 4262560
> 1244872
> 4199215
> 0
> 4262560

> Here's the code: both solutions and general critique are welcome.

> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>

> #define MAXCARDS 40

> int * shuffle_cards(void);

> int main(int argc, char * argv[])
> {
>         int deck[MAXCARDS];
>         int * deck_ptr;
>         int i;

>         deck_ptr = malloc(sizeof(deck[MAXCARDS]));

>         deck_ptr = shuffle_cards();

>         for (i = 0; i < MAXCARDS; i++)
>                 printf("%d\n", *(deck_ptr + i));

>         return (0);
> }

> int * shuffle_cards(void)
> {
>         int i;
>         int * new_deck;
>         int deck[MAXCARDS] = {
>                 1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,
>                 6,6,6,6,7,7,7,7,8,8,8,8,9,9,9,9,10,10,10,10
>         };

>         new_deck = deck;

>         for (i = 0; i < MAXCARDS; i++)
>                 printf("%d\n", *(new_deck + i));

>         return new_deck;
> }

> Please remove obvious characters from my e-mail address when e-mailing me.



Sun, 01 Jul 2001 03:00:00 GMT  
 problem returning pointer from function

Victor,

After listening to the advice from several experienced programmers see
if you can re-write the program again.

We'll give you more constructive critism until your program is free
from bugs and bad programming practises.

Re-write your program and post it out again.

Jason



Sun, 01 Jul 2001 03:00:00 GMT  
 problem returning pointer from function

Quote:

>much good advice here -- just one more thing:
>don't forget to free your allocations.  not all OSs will clean this up for
>you.

That's certainly good practice in most cases. However be aware that the
concepts of freeing malloc'd memory and releasing program resources back
to the OS when the program terminates are two essentially unrelated concepts.
Can you name an OS that doesn't clean up properly? (this was discussed
recently on comp.lang.c.moderated)

--
-----------------------------------------


-----------------------------------------



Mon, 02 Jul 2001 03:00:00 GMT  
 problem returning pointer from function
OK, here's the new and improved code, and it appears to do what I had
hoped.

I am a bit confused about how to free this memory.  I can't
free(deck_ptr) before I exit main, can I?

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define MAXCARDS 40

int * shuffle_cards(int * d_ptr);

int main(int argc, char * argv[])
{
        int deck[MAXCARDS] = {
                1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,
                6,6,6,6,7,7,7,7,8,8,8,8,9,9,9,9,10,10,10,10
        };
        int * deck_ptr;
        int i;

        deck_ptr = shuffle_cards(deck);

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

        return (0);

Quote:
}

int * shuffle_cards(int * d_ptr)
{
        int j=0;
        int pos;
        int * new_deck;
        int high_spot = MAXCARDS - 1;

        srand( (unsigned)time( NULL ) );

        j = 0;

        new_deck=malloc(sizeof(*d_ptr));

        /* Randomize the deck */
        while (high_spot > 0) {
                pos = (rand() % high_spot) + 1;
                *(new_deck + j) = *(d_ptr + pos);
                *(d_ptr + pos) = *(d_ptr + high_spot);
                j++;
                high_spot--;
                if (high_spot == 0)
                        *(new_deck + j) = *(d_ptr);
        }

        return new_deck;

Quote:
}


Quote:

>Victor,

>After listening to the advice from several experienced programmers see
>if you can re-write the program again.

>We'll give you more constructive critism until your program is free
>from bugs and bad programming practises.

>Re-write your program and post it out again.

>Jason

Please remove obvious characters from my e-mail address when e-mailing me.


Mon, 02 Jul 2001 03:00:00 GMT  
 problem returning pointer from function

If you are going to exit the program, there is
no particular need to free() one or another of
your dynamically allocated chunks of memory.

But it is a good idea to be in the habit of knowing
who is allocating memory and who is responsible for
freeing it; larger systems that persist for longer
times demand careful management.

With this thought in mind, sometimes it is useful to
seek algorithms that do not require allocation of
memory. Card deck shuffling is one of these, if there
is no reason to maintain the image of the deck as it
was before you shuffled. I'm assuming that your interest
here is to randomize the deck, not to simulate one or
another of the actual card shuffling algorithms ...

I'd generally pass the number of cards as a parameter
to the shuffle routine, but for now let's keep your
calling sequence in tact:

#define    MAXCARDS    ... /* your number here */

int *
shuffle_cards(int *deck)
{
    int        ncard = MAXCARDS;

    /* cct is how many cards are in the deck to
    ** be shuffled. Each time around the loop,
    ** we pull one random card to be the "last"
    ** card in the deck, then loop back to shuffle
    ** the rest of them.
    */
    while (ncard-- > 1) {
        /* "which" may be "lastv" here: we might use the old
        ** last card as the new last card. Feel free to use
        ** a random number generator better than "rand".
        */
        int    which = rand() % (ncard +1);
        int    lastv = deck[ncard];
        deck[ncard] = deck[which];
        deck[which] = lastv;
    }
    return deck;

Quote:
}

>OK, here's the new and improved code, and it appears to do what I had
>hoped.

>I am a bit confused about how to free this memory.  I can't
>free(deck_ptr) before I exit main, can I?

>#include <stdio.h>
>#include <stdlib.h>
>#include <time.h>

>#define MAXCARDS 40

>int * shuffle_cards(int * d_ptr);

>int main(int argc, char * argv[])
>{
> int deck[MAXCARDS] = {
> 1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,
> 6,6,6,6,7,7,7,7,8,8,8,8,9,9,9,9,10,10,10,10
> };
> int * deck_ptr;
> int i;

> deck_ptr = shuffle_cards(deck);

> for (i = 0; i < MAXCARDS; i++)
> printf("%d\n", *(deck_ptr + i));

> return (0);
>}

>int * shuffle_cards(int * d_ptr)
>{
> int j=0;
> int pos;
> int * new_deck;
> int high_spot = MAXCARDS - 1;

> srand( (unsigned)time( NULL ) );

> j = 0;

> new_deck=malloc(sizeof(*d_ptr));

> /* Randomize the deck */
> while (high_spot > 0) {
> pos = (rand() % high_spot) + 1;
> *(new_deck + j) = *(d_ptr + pos);
> *(d_ptr + pos) = *(d_ptr + high_spot);
> j++;
> high_spot--;
> if (high_spot == 0)
> *(new_deck + j) = *(d_ptr);
> }

> return new_deck;
>}



Mon, 02 Jul 2001 03:00:00 GMT  
 problem returning pointer from function


Quote:

>I think that this should work, but it doesn't.  Inside the function,
>*(new_deck + i) prints just fine.

>Back in main, I only get:

>1
>1
>1
>1
>2
>2
>2
>2
>3
>3
>3
>3
>4
>4
>4
>4
>872415237
>0
>1
>1244787
>0
>0
>4207541
>0
>2012894640
>2012660170
>2147348480
>4262560
>1244872
>4199215
>0
>4262560

>Here's the code: both solutions and general critique are welcome.

>#include <stdio.h>
>#include <stdlib.h>
>#include <string.h>

>#define MAXCARDS 40

>int * shuffle_cards(void);

>int main(int argc, char * argv[])
>{
>    int deck[MAXCARDS];
>    int * deck_ptr;
>    int i;

>    deck_ptr = malloc(sizeof(deck[MAXCARDS]));

>    deck_ptr = shuffle_cards();

>    for (i = 0; i < MAXCARDS; i++)
>            printf("%d\n", *(deck_ptr + i));

>    return (0);
>}

>int * shuffle_cards(void)
>{
>    int i;
>    int * new_deck;
>    int deck[MAXCARDS] = {
>            1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,
>            6,6,6,6,7,7,7,7,8,8,8,8,9,9,9,9,10,10,10,10
>    };

>    new_deck = deck;

>    for (i = 0; i < MAXCARDS; i++)
>            printf("%d\n", *(new_deck + i));

>    return new_deck;
>}

The main problem I see is that you declare deck within the function and are
trying to pass it back to main.  Yet deck is declared on the stack so when you
exit that function deck's address may no longer be valid.  the address space
has been freed from the stack and is available for other C functions and the
data in it may be inadvertently over-written.  Malloc the area for deck,
initialize it, and pass that address back to the calling program which will
free it when done.


Sun, 15 Jul 2001 03:00:00 GMT  
 
 [ 12 post ] 

 Relevant Pages 

1. Pointer to function returning pointer to function returning...

2. Question about signal()/pointers to functions that return pointers to functions

3. problem about pointer used as function return type

4. Can function returning pointer return negative integers?

5. Returning Pointer To Pointer From Function

6. How to use (pointer to function), and function and pointer to (pointer to function)

7. C++ function pointers versus C function pointer problem

8. Function returning a function-pointer - how to prototype ?

9. Declaring static function returning pointer to extern function

10. About function that returns function pointer

11. Function returning pointers to functions (repost)

12. Function returning pointers to functions

 

 
Powered by phpBB® Forum Software