Thread: Problem with passing structs to a function.

  1. #1
    Registered User
    Join Date
    Mar 2008
    Posts
    3

    Problem with passing structs to a function.

    I'm currently working on some homework that is suppose to be a library of functions that make something like a non-null terminated string. It was due yesturday, and I'm all out of ideas for the last part though. As far as I can tell, the code all works except when I need to update elements of a struct while inside of a function. I've found this is a problem to be an issue with the function using a copy of the struct and not updating the actual struct. pass by value.. Well the only fixes that I could find for this kind of problem involved using a pointer to a pointer in the functions, but this won't work in my program because I have a typedef that I have to use, and the functions are already declared, I just need to fill in the body and also make the struct itself.

    If anyone could help me figure out a way to update the actually struct while inside of the functions, that would be awesome. Here's the struct, the malloc, and free fucnction, as well as the typedef from the header file. Out of these, the only problem I see is in the free function. When x is freed, but but actually set to null after the return. I also have a bunch of other functions that I already wrote, but they have the same problem, not updating after the function ends. Any help would be great, thanks

    Code:
    typedef struct foo * Foo;
    
    struct foo{
      size_t currentSize;
      size_t maxSize;
      char string[1];
    };
    
    Foo FooMalloc(size_t size){
      Foo x = (Foo)malloc(sizeof(struct foo) + ((2 * size) * sizeof(char)));
      if(x == NULL){
        fprintf(stderr, "Not enough memory, exiting program");
        exit(100);
      }
    
      x->currentSize = 0;
      x->maxSize = 2 * size;
      return x;
    }
    
    void FooFree(Foo x){
      if (x == NULL){
        /* Foo has already been freed */
      } else {
        free(x);
        x = NULL;
      }
    }

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    The only way you can change the value of anything OUTSIDE of a function is by passing the address of it, so in this case, free would need take a pointer to Foo.

    You can always change the CONTENT of a Foo, since it is a pointer in the first place, but you can't change the Foo item itself, since it's not a pointer.

    Just like if you pass an integer:
    Code:
    void func(int x)
    {
       x = 7;
    }
    // caller's parameter is unchanged. 
    
    void func2(int *x)
    {
       *x = 7;
    }
    // Caller will have the variable changed.
    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    uint64_t...think positive xuftugulus's Avatar
    Join Date
    Feb 2008
    Location
    Pacem
    Posts
    355
    How about:
    Code:
    void FooFree(Foo *x){
      if (*x == NULL){
        /* Foo has already been freed */
      } else {
        free(*x);
        *x = NULL;
      }
    }
    Which is used like:
    Code:
    FooFree(&pointerToAFooObject);
    This code will modify the pointerToAFooObject variable, effectively NULL'ing it after the function call.

    For the rest of it i can see that you are passing and returning the struct in a pointer fashion already, which should result in it being modifiable inside your other functions, provided you pass it using the typedef i see.
    Code:
    ...
        goto johny_walker_red_label;
    johny_walker_blue_label: exit(-149$);
    johny_walker_red_label : exit( -22$);
    A typical example of ...cheap programming practices.

  4. #4
    Registered User
    Join Date
    Mar 2008
    Posts
    3
    Quote Originally Posted by xuftugulus View Post
    Which is used like:
    Code:
    FooFree(&pointerToAFooObject);
    This code will modify the pointerToAFooObject variable, effectively NULL'ing it after the function call.

    For the rest of it i can see that you are passing and returning the struct in a pointer fashion already, which should result in it being modifiable inside your other functions, provided you pass it using the typedef i see.
    Those are the only kind of fix I could ever seem to find, but since the functions are declared in the pre-made header file, I can't change the parameter from "Foo x" to "Foo* x". I thought perhaps that might be a way to change the struct so that it could be accessed though a pointer, but some aspects of structs are still kind of confusing to me, and I'm not really sure if there is anything to do. I saw another post somewhere where one guy had a made a typedef that seemed like it would for for this, but I'm not sure I can do it with with the typedef that I have, since I can't change the typedef either. His struct was something like:

    Code:
    struct foo{
      size_t currentSize;
      size_t maxSize;
      char string[1];
    }bar[1];

  5. #5
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    I hate typedef'd pointers -- I think they just obfuscate.

    Wouldn't you want a structure something like this?
    Code:
    struct foo
    {
       size_t currentSize;
       size_t maxSize;
       char *string;
    };
    And when you create the Foo, allocate space like this?
    Code:
    Foo FooMalloc(size_t size)
    {
       Foo x = malloc(sizeof *x);
       if ( x )
       {
          x->currentSize = 0;
          x->maxSize = size;
          x->string = malloc(size);
          if ( !x->string )
          {
             return 0;
          }
       }
       return x;
    }
    And then have a free like this?
    Code:
    void FooFree(Foo x)
    {
       if ( x == NULL )
       {
          /* Foo has already been freed */
       }
       else
       {
          free(x->string);
          free(x);
          x = NULL;
       }
    }
    [edit]But if you've got to do the struct hack: http://david.tribble.com/text/cdiffs.htm#C99-fam
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  6. #6
    uint64_t...think positive xuftugulus's Avatar
    Join Date
    Feb 2008
    Location
    Pacem
    Posts
    355
    Quote Originally Posted by darsh1120 View Post
    Those are the only kind of fix I could ever seem to find, but since the functions are declared in the pre-made header file, I can't change the parameter from "Foo x" to "Foo* x".
    Then you can't make the function alter the value of the called on pointer.
    Code:
    ...
        goto johny_walker_red_label;
    johny_walker_blue_label: exit(-149$);
    johny_walker_red_label : exit( -22$);
    A typical example of ...cheap programming practices.

  7. #7
    Registered User
    Join Date
    Mar 2008
    Posts
    3
    I haven't tried it, but I had the idea, what if the struct also had 2 int pointers in it that pointed to the current and max size ints? Would the function be able to update the struct through those? and if so, are they any problems with that/ good reasons not to?

  8. #8
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    You can ALREADY update the current/max sizes in the structure you use. No need for further indirection.

    And if you can't update the prototype for Free(), then you have no possibility of changing x to NULL inside the function.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 4
    Last Post: 05-13-2011, 08:28 AM
  2. problem with passing value of a function
    By Lince in forum C Programming
    Replies: 7
    Last Post: 02-12-2009, 08:39 AM
  3. Compiling sample DarkGDK Program
    By Phyxashun in forum Game Programming
    Replies: 6
    Last Post: 01-27-2009, 03:07 AM
  4. <Gulp>
    By kryptkat in forum Windows Programming
    Replies: 7
    Last Post: 01-14-2006, 01:03 PM
  5. Big Problem With Passing an Matrix to Main Function
    By Maragato in forum C Programming
    Replies: 4
    Last Post: 06-14-2004, 11:06 PM