Why, oh why? Parameter passing with arrays of structs.

This is a discussion on Why, oh why? Parameter passing with arrays of structs. within the C Programming forums, part of the General Programming Boards category; I recently posted a thread on parameter passing by reference. Check http://cboard.cprogramming.com/showthread.php?t=95229 Thanks to you guys, I managed to have ...

  1. #1
    Registered User d3m105's Avatar
    Join Date
    Oct 2007
    Location
    Mauritius
    Posts
    3

    Unhappy Why, oh why? Parameter passing with arrays of structs.

    I recently posted a thread on parameter passing by reference. Check Passing by Reference. Simple question.

    Thanks to you guys, I managed to have it work in all of my functions, except one. That's the function which accepts an array of struct.

    Here's a simplified example of the code:

    Code:
    #include <stdio.h>
    #include <conio.h>
    
    struct Test
    {
        int a;
        int b;  
    };    
    
    int main()
    {
        struct Test myStructs[5];
        InitStructs(&myStructs);
        return 0;
    }    
    
    void InitStructs(struct Test * myStructs[5])
    {
        int i = 0;
        for (i=0; i<=5; i++)
        {
            myStructs[i]->a = 10;
            myStructs[i]->b = 50;
        }
    }
    This time, it compiles. But crashes as soon as I run the example.
    Am I doing anything wrong?

    I'm at the very end of my project. Just a few lines of code are missing, and I want to do it the right way Can anybody help?

    Thank you so much!

    -Rowan

  2. #2
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,046
    Code:
    void InitStructs(struct Test * myStructs[5])
    There's a difference between these two declarations:
    Code:
    int (*array)[5];  /* array of 5 pointers to int */
    int *(array[5]);  /* pointer to array with 5 int elements */
    When you leave off the parentheses, the effect is the same as the former. However, in your case, you're looking for the latter. So something like this should work:
    Code:
    void InitStructs(struct Test *(myStructs[5]))
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  3. #3
    cas
    cas is offline
    Registered User
    Join Date
    Sep 2007
    Posts
    975
    When you leave off the parentheses, the effect is the same as the former
    That's backward, actually:
    Code:
    int (*array)[5]; /* this is a pointer to an array */
    int *array[5];   /* this is an array of pointers */
    int *(array[5]); /* this is also an array of pointers */
    To d3m105: Your code as posted is not correct. You're calling InitStructs() before you give the prototype; don't do that, because prototypes allow your compiler to do type-checking on function calls.

    If you do this:
    Code:
    struct Test { int a; };
    void InitStructs(struct Test * myStructs[5]); /* this is a prototype */
    int main(void)
    {
      struct Test myStructs[5];
      InitStructs(&myStructs);
      return 0;
    }
    void InitStructs(struct Test * myStructs[5]) {}
    Your compiler should tell you that you're passing the wrong type. Always, always use prototypes for your functions.

    To get this working, use something like this:
    Code:
    struct Test { int a; };
    void InitStructs(struct Test myStructs[]);
    int main(void)
    {
      struct Test myStructs[5];
      InitStructs(myStructs);
      return 0;
    }
    void InitStructs(struct Test myStructs[]) {}
    If you really want to pass a pointer to the array by using &myStructs (which you almost surely don't except as an academic exercise) it's slightly more complex. I'd rather not type yet another block unless you have a real interest in seeing how pointers to arrays work.

    The method I showed you above is about as close to transparent pass by reference you'll find in C. It's really not pass by reference, but inside your InitStructs() function you can treat myStructs like an array of struct, for the most part.

  4. #4
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,422
    When you've fixed the issues mentioned by cas, then you have an array overrun.

    > for (i=0; i<=5; i++)
    It should be <5, not <=5
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Passing Multidementional arrays
    By kingneb in forum C++ Programming
    Replies: 2
    Last Post: 10-25-2008, 03:24 PM
  2. Alternative to passing context as a parameter
    By Jayasuriya in forum C Programming
    Replies: 4
    Last Post: 08-23-2008, 11:01 PM
  3. Replies: 4
    Last Post: 05-08-2005, 10:12 AM
  4. scanf(), Parameter Passing, and Character Arrays
    By linguae in forum C Programming
    Replies: 2
    Last Post: 05-02-2005, 04:19 AM
  5. passing arrays
    By Sarah in forum C++ Programming
    Replies: 4
    Last Post: 10-25-2001, 02:50 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21