Thread: Returning a pointer to a struct array

  1. #1
    Registered User
    Join Date
    Apr 2007
    Posts
    42

    Returning a pointer to a struct array

    Hi all,

    I have the below function which I want to return a pointer to the array of type struct. However, I'm unsure of the syntax; what do I need to type as the return type of the function and in the prototype? I have tried the following (as per what I'd read in similar threads online):

    Code:
    struct *initialise()
    but that doesn't work.

    Also with regards to returning the pointer which of the following would be correct:

    Code:
    return *playersPtr;
    return &playersPtr;
    return playerPtr;
    Code:
    int initialise()
    {
        int currentPlayer = 0;   
           
        struct player
        { 
            int cnt_scoreC, cnt_scoreT, cnt_startScore, numDarts, cnt_legs, 
                cnt_sets, clk_currentNum, clk_startNum, s_numDarts, s_won,
                s_lost, s_played;
            float cnt_dartAve;
            char name[15];
        };
    
        struct player players[MAXPLAYERS];  //players struct array  
        struct player *playersPtr; //pointer capable of pointing to struct player
        playersPtr = &players[MAXPLAYERS]; //put address of players array into players pointer
        
        //return playersPtr;
    }
    Thanks in advance.

    PS: I have put comments next to the pointer stuff on what I thought was happening, can anyone confirm if this is right?

  2. #2
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by osiris^ View Post
    I'm unsure of the syntax; what do I need to type as the return type of the function and in the prototype? I have tried the following (as per what I'd read in similar threads online):
    [...]
    but that doesn't work.
    "That doesn't work" is as vague as you can get.

    Presuming the issue is that you are getting some error/warning like "returns address of local variable" it is for the same reason you cannot do this:
    Code:
    char *myfunc () {
           char string[]="hello world";
           return string;
    Do you understand what is wrong with that? You are trying to do the same thing with a struct.

    However, that is probably not your only problem here. You will have to be more specific about what "that doesn't work" means.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  3. #3
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    the prototype should be

    Code:
    struct player * initialize(void);
    and as said - you should not return pointer to the local variable;
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  4. #4
    Registered User
    Join Date
    Apr 2007
    Posts
    42
    Quote Originally Posted by MK27 View Post
    "That doesn't work" is as vague as you can get.

    Presuming the issue is that you are getting some error/warning like "returns address of local variable" it is for the same reason you cannot do this:
    Code:
    char *myfunc () {
           char string[]="hello world";
           return string;
    Do you understand what is wrong with that? You are trying to do the same thing with a struct.

    However, that is probably not your only problem here. You will have to be more specific about what "that doesn't work" means.
    I presume it's because the return type was defined as char, but a string is being returned?

    I have changed the function now to what vart suggested and it compiles fine. Am I right in saying that a pointer is returned from that function that I can use to assign to other variables in other functions? Or is that what you both said when not to return a pointer to a local variable? If so why is this a problem?

    Sorry, I also complain when people tell me it 'doesn't work' without any explanation - can't believe I did it myself!

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    You can't (or must not) return a pointer to a local variable (because it will not exist once the function is finished!).
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #6
    Registered User
    Join Date
    Apr 2007
    Posts
    42
    Quote Originally Posted by Elysia View Post
    You can't (or must not) return a pointer to a local variable (because it will not exist once the function is finished!).
    So assuming I want to create a struct in one function and have lots of other functions interact with it in some way (not at the same time though) how would you go about implementing that?

    Can I pass/return struct arrays to functions as the program runs? I just presumed I'd need a pointer to do it.

  7. #7
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by osiris^ View Post
    So assuming I want to create a struct in one function and have lots of other functions interact with it in some way (not at the same time though) how would you go about implementing that?

    Can I pass/return struct arrays to functions as the program runs? I just presumed I'd need a pointer to do it.
    Welcome to the world of malloc. (Or alternatively, you can create the array in main and pass it in -- arrays are passed by pointer automatically so any changes made in the function are visible in main as well.)

  8. #8
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    You cannot return arrays.
    You can pass variables (by address) to functions. This is the usual way of doing it since it allows the caller to determine how the buffer it passes in is allocated.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  9. #9
    Registered User
    Join Date
    Jun 2009
    Location
    US of A
    Posts
    305
    Quote Originally Posted by osiris^ View Post
    I presume it's because the return type was defined as char, but a string is being returned?
    No it is because you are returning a pointer to a local variable which goes out of scope as soon as the function is exited.

  10. #10
    Registered User
    Join Date
    May 2009
    Posts
    49
    Shouldn't the struct be outside your function? If you want the pointers to be valid both the scope of the array of the structs and the pointer must be outside the worker function.

  11. #11
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Global variables are not particularly good either. It's better to pass in required arguments.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  12. #12
    Registered User
    Join Date
    Apr 2007
    Posts
    42
    Hi all, I've read through all your replies and thought I'd just clarify what exactly I'm trying to do and what my problem is.

    I have a struct called player with various attributes, and an array of these called players. I need this struct array to be created on startup, but I then need to add players to this struct array up to MAXPLAYERS (which is 100), each time the addPlayer function is called.

    I've tried a few different things - including the pointer based stuff which appears to be wrong - and was trying to avoid global variables. I'm currently thinking, as suggested above, to create the struct and struct array in main, and then pass this to addPlayer or one of the game functions (some game functions will load players from the struct array so will need to be able to see it) as needed.

    Is this wrong? If so, why? What is the best, preferably most straight-forward way of acheiving this functionality? As you can probably tell I'm not a programmer, but am trying to get better at it and I'm finding this a little awkward.

  13. #13
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    If you know there can only be MAXPLAYERS players (and you have room for it, which you probably do), then just create an array of MAXPLAYERS structs and be done with it. You can keep a separate variable of "next player to be filled in" and pass the array and the variable (by pointer, so that it can be updated) to your addPlayer function.

  14. #14
    Registered User
    Join Date
    Apr 2007
    Posts
    42
    Quote Originally Posted by tabstop View Post
    If you know there can only be MAXPLAYERS players (and you have room for it, which you probably do), then just create an array of MAXPLAYERS structs and be done with it. You can keep a separate variable of "next player to be filled in" and pass the array and the variable (by pointer, so that it can be updated) to your addPlayer function.
    Which takes me back to the original thread topic; how do I do that? I wrote what I thought did that and was told by a couple of posters that I could not pass a pointer to a local variable because it would be out of scope.

    Here it is:

    Code:
    struct player * initialise()
    {
        int currentPlayer = 0;   
           
        struct player
        { 
            int cnt_scoreC, cnt_scoreT, cnt_startScore, numDarts, cnt_legs, 
                cnt_sets, clk_currentNum, clk_startNum, s_numDarts, s_won,
                s_lost, s_played;
            float cnt_dartAve;
            char name[15];
        };
    
        struct player players[MAXPLAYERS];  //players struct array  
        struct player *playersPtr; //pointer capable of pointing to struct player
        playersPtr = &players[MAXPLAYERS]; //put address of players array into players pointer
        
        return playersPtr;
    As I will need to 'pick up' that pointer in other functions and use it to modify the struct array, is 'return playersPtr;' valid?

    In the other functions, assuming it's addPlayer, I will need to 'pick up' the return value of the above initialise function and then use it in the addPlayer function to edit the array. What variable type would that be assigned to in the addPlayer function? Would I create another struct pointer and assign to that? More specifically, if I was returning an int from function one(), to use that value inside function two() I'd type 'int number = one();' But how do I do that in this case?

  15. #15
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Either you use malloc/free or you pass in a buffer:
    Code:
    void initialise(struct player* players[])
    Or
    Code:
    playersPtr = malloc( sizeof(*playersPtr) * MAXPLAYERS );
    return playersPtr;
    // And when finished using it
    free(playersPtr);
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. sorting number
    By Leslie in forum C Programming
    Replies: 8
    Last Post: 05-20-2009, 04:23 AM
  2. sorting the matrix question..
    By transgalactic2 in forum C Programming
    Replies: 47
    Last Post: 12-22-2008, 03:17 PM
  3. Global Variables
    By Taka in forum C Programming
    Replies: 34
    Last Post: 11-02-2007, 03:25 AM
  4. Unknown Memory Leak in Init() Function
    By CodeHacker in forum Windows Programming
    Replies: 3
    Last Post: 07-09-2004, 09:54 AM
  5. Quick question about SIGSEGV
    By Cikotic in forum C Programming
    Replies: 30
    Last Post: 07-01-2004, 07:48 PM