Global pointer pointing to locally defined type

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Andrej Prsa

    #16
    Re: Global pointer pointing to locally defined type

    Hi!
    [color=blue][color=green]
    > > If this doesn't work, how
    > > could I make it work? Do I have to allocate memory for this int
    > > and copy the original int to that and then point value to this
    > > newly allocated int?[/color][/color]
    [color=blue]
    > That would work, but you mustn't forget to deallocate it afterwards,
    > or you'll end up with a memory leak. Your program would crash or
    > starve.[/color]

    This particular function builds a global parameter table and once it's
    complete, it isn't modified ever again. When the program is about to
    finish, I free all parameter values consecutively. This brings me to
    another question: I have read at numerous places that freeing memory just
    before the end of the program isn't necessary, since the OS claims the
    memory back when the program execution is over. Is this true?

    Thanks,

    Andrej

    Comment

    • Andrej Prsa

      #17
      Re: Global pointer pointing to locally defined type

      Hi!
      [color=blue][color=green]
      > > If this doesn't work, how
      > > could I make it work? Do I have to allocate memory for this int
      > > and copy the original int to that and then point value to this
      > > newly allocated int?[/color][/color]
      [color=blue]
      > That would work, but you mustn't forget to deallocate it afterwards,
      > or you'll end up with a memory leak. Your program would crash or
      > starve.[/color]

      This particular function builds a global parameter table and once it's
      complete, it isn't modified ever again. When the program is about to
      finish, I free all parameter values consecutively. This brings me to
      another question: I have read at numerous places that freeing memory just
      before the end of the program isn't necessary, since the OS claims the
      memory back when the program execution is over. Is this true?

      Thanks,

      Andrej

      Comment

      • Bernhard Holzmayer

        #18
        Re: Global pointer pointing to locally defined type

        Andrej Prsa wrote:
        [color=blue]
        > Hi!
        >[color=green][color=darkred]
        >> > If this doesn't work, how
        >> > could I make it work? Do I have to allocate memory for this int
        >> > and copy the original int to that and then point value to this
        >> > newly allocated int?[/color][/color]
        >[color=green]
        >> That would work, but you mustn't forget to deallocate it
        >> afterwards, or you'll end up with a memory leak. Your program
        >> would crash or starve.[/color]
        >
        > This particular function builds a global parameter table and once
        > it's complete, it isn't modified ever again. When the program is
        > about to finish, I free all parameter values consecutively. This
        > brings me to another question: I have read at numerous places that
        > freeing memory just before the end of the program isn't necessary,
        > since the OS claims the memory back when the program execution is
        > over. Is this true?
        >
        > Thanks,
        >
        > Andrej[/color]

        I guess you do the same thing, if you define a local variable in a
        block like
        {
        int x;
        use_of_x(x);
        x = x+1;
        ...
        }
        the closing bracket removes the variable from the heap or from the
        stack, wherever it has been allocated.

        If you explicitely allocate memory, it's taken from heap or stack,
        which has been granted to this program, and will be returned to the
        OS after termination of the program.
        Usually, you'll find this situation, which means that you're right.

        This might be different if you use your own memory management
        and allocate memory from additional resources which the compiler
        isn't aware of. If you don't know how this works, you will
        certainly not have to bother.

        Bernhard


        Comment

        • Bernhard Holzmayer

          #19
          Re: Global pointer pointing to locally defined type

          Andrej Prsa wrote:
          [color=blue]
          > Hi!
          >[color=green][color=darkred]
          >> > If this doesn't work, how
          >> > could I make it work? Do I have to allocate memory for this int
          >> > and copy the original int to that and then point value to this
          >> > newly allocated int?[/color][/color]
          >[color=green]
          >> That would work, but you mustn't forget to deallocate it
          >> afterwards, or you'll end up with a memory leak. Your program
          >> would crash or starve.[/color]
          >
          > This particular function builds a global parameter table and once
          > it's complete, it isn't modified ever again. When the program is
          > about to finish, I free all parameter values consecutively. This
          > brings me to another question: I have read at numerous places that
          > freeing memory just before the end of the program isn't necessary,
          > since the OS claims the memory back when the program execution is
          > over. Is this true?
          >
          > Thanks,
          >
          > Andrej[/color]

          I guess you do the same thing, if you define a local variable in a
          block like
          {
          int x;
          use_of_x(x);
          x = x+1;
          ...
          }
          the closing bracket removes the variable from the heap or from the
          stack, wherever it has been allocated.

          If you explicitely allocate memory, it's taken from heap or stack,
          which has been granted to this program, and will be returned to the
          OS after termination of the program.
          Usually, you'll find this situation, which means that you're right.

          This might be different if you use your own memory management
          and allocate memory from additional resources which the compiler
          isn't aware of. If you don't know how this works, you will
          certainly not have to bother.

          Bernhard


          Comment

          • Bernhard Holzmayer

            #20
            Re: Global pointer pointing to locally defined type

            Andrej Prsa wrote:
            [color=blue]
            > Hi!
            >[color=green][color=darkred]
            >> >> > If this doesn't work, how could I make
            >> >> > it work? Do I have to allocate memory for this int and copy
            >> >> > the
            >> >original> > int to that and then point value to this newly
            >> >allocated int?>
            >> >> That could be one way, yes.[/color]
            >>[color=darkred]
            >> > Is there any better way you'd suggest?[/color]
            >>
            >> Pass the address of a variable as a parameter to your function.[/color]
            >
            > Unfortunately, I cannot do that, since I don't have the actual
            > variables when calling this function, rather the actual constants,
            > and e.g. &5 obviously doesn't work directly. I would lose
            > transparency if I used int a = 5; and then passing &a to the
            > function, because this function is called a zillion times with
            > default parameter values.
            >
            > Thanks,
            >
            > Andrej[/color]

            Maybe you can use a global variable which you fill with the
            parameters, and then call the function without parameters.
            In this case, you'd avoid the lifetime problem.

            Bernhard

            Comment

            • Bernhard Holzmayer

              #21
              Re: Global pointer pointing to locally defined type

              Andrej Prsa wrote:
              [color=blue]
              > Hi!
              >[color=green][color=darkred]
              >> >> > If this doesn't work, how could I make
              >> >> > it work? Do I have to allocate memory for this int and copy
              >> >> > the
              >> >original> > int to that and then point value to this newly
              >> >allocated int?>
              >> >> That could be one way, yes.[/color]
              >>[color=darkred]
              >> > Is there any better way you'd suggest?[/color]
              >>
              >> Pass the address of a variable as a parameter to your function.[/color]
              >
              > Unfortunately, I cannot do that, since I don't have the actual
              > variables when calling this function, rather the actual constants,
              > and e.g. &5 obviously doesn't work directly. I would lose
              > transparency if I used int a = 5; and then passing &a to the
              > function, because this function is called a zillion times with
              > default parameter values.
              >
              > Thanks,
              >
              > Andrej[/color]

              Maybe you can use a global variable which you fill with the
              parameters, and then call the function without parameters.
              In this case, you'd avoid the lifetime problem.

              Bernhard

              Comment

              • Al Bowers

                #22
                Re: Global pointer pointing to locally defined type



                Andrej Prsa wrote:[color=blue]
                > Hi!
                >
                >[color=green][color=darkred]
                >>>If this doesn't work, how could I make
                >>>it work? Do I have to allocate memory for this int and copy the original
                >>>int to that and then point value to this newly allocated int?[/color]
                >>
                >>That could be one way, yes.[/color]
                >
                >
                > Is there any better way you'd suggest?
                >[/color]

                Another way, perhaps not better, is the use of a static
                variable.

                #include <stdio.h>

                void *value;

                void dummy_func (int a)
                {
                static int buf;

                buf = a;
                value = &buf;
                return;
                }

                int main(void)
                {
                dummy_func(21);
                printf("Stored in value = %d\n",*(int *)value);
                return 0;
                }



                --
                Al Bowers
                Tampa, Fl USA
                mailto: xabowers@myrapi dsys.com (remove the x to send email)
                Latest news coverage, email, free stock quotes, live scores and video are just the beginning. Discover more every day at Yahoo!


                Comment

                • Al Bowers

                  #23
                  Re: Global pointer pointing to locally defined type



                  Andrej Prsa wrote:[color=blue]
                  > Hi!
                  >
                  >[color=green][color=darkred]
                  >>>If this doesn't work, how could I make
                  >>>it work? Do I have to allocate memory for this int and copy the original
                  >>>int to that and then point value to this newly allocated int?[/color]
                  >>
                  >>That could be one way, yes.[/color]
                  >
                  >
                  > Is there any better way you'd suggest?
                  >[/color]

                  Another way, perhaps not better, is the use of a static
                  variable.

                  #include <stdio.h>

                  void *value;

                  void dummy_func (int a)
                  {
                  static int buf;

                  buf = a;
                  value = &buf;
                  return;
                  }

                  int main(void)
                  {
                  dummy_func(21);
                  printf("Stored in value = %d\n",*(int *)value);
                  return 0;
                  }



                  --
                  Al Bowers
                  Tampa, Fl USA
                  mailto: xabowers@myrapi dsys.com (remove the x to send email)
                  Latest news coverage, email, free stock quotes, live scores and video are just the beginning. Discover more every day at Yahoo!


                  Comment

                  • Dan Pop

                    #24
                    Re: Global pointer pointing to locally defined type

                    In <7837740.FMRdip IP5t@holzmayer. ifr.rt> Bernhard Holzmayer <holzmayer.bern hard@deadspam.c om> writes:
                    [color=blue]
                    >Andrej Prsa wrote:
                    >[color=green]
                    >> Hi![/color]
                    >Hi Andrej,
                    >[color=green]
                    >>
                    >> What happens to a globally defined pointer, e.g.
                    >>
                    >> void *value;
                    >>
                    >> that points to a particular type in a function:
                    >>
                    >> int dummy_func (int a)
                    >> {
                    >> value = &a;
                    >> return 0;
                    >> }
                    >>
                    >> after the function returns to main?[/color]
                    >I agree to Joona's opinion: it's undefined.
                    >If the pointer is evaluated before its content has been modified,
                    >it might work. But since you cannot rely on this, don't do it.
                    >Even worse, some compilers transfer the parameter via a register,
                    >so that a doesn't have an address location, and the pointer
                    >evaluation would fail.[/color]

                    Nonsense! a DOES have an address inside dummy_func, regardless of how its
                    value was passed by the compiler and it's *always* legal to take its
                    address inside the function. The address becomes illegal after the
                    function returns. The canonical example is:

                    int *f(int a)
                    {
                    return &a;
                    }

                    or the similar

                    int *g(void)
                    {
                    int a;
                    return &a;
                    }

                    It is OK to call these functions *only* if their return value is
                    discarded.

                    Dan
                    --
                    Dan Pop
                    DESY Zeuthen, RZ group
                    Email: Dan.Pop@ifh.de

                    Comment

                    • Dan Pop

                      #25
                      Re: Global pointer pointing to locally defined type

                      In <7837740.FMRdip IP5t@holzmayer. ifr.rt> Bernhard Holzmayer <holzmayer.bern hard@deadspam.c om> writes:
                      [color=blue]
                      >Andrej Prsa wrote:
                      >[color=green]
                      >> Hi![/color]
                      >Hi Andrej,
                      >[color=green]
                      >>
                      >> What happens to a globally defined pointer, e.g.
                      >>
                      >> void *value;
                      >>
                      >> that points to a particular type in a function:
                      >>
                      >> int dummy_func (int a)
                      >> {
                      >> value = &a;
                      >> return 0;
                      >> }
                      >>
                      >> after the function returns to main?[/color]
                      >I agree to Joona's opinion: it's undefined.
                      >If the pointer is evaluated before its content has been modified,
                      >it might work. But since you cannot rely on this, don't do it.
                      >Even worse, some compilers transfer the parameter via a register,
                      >so that a doesn't have an address location, and the pointer
                      >evaluation would fail.[/color]

                      Nonsense! a DOES have an address inside dummy_func, regardless of how its
                      value was passed by the compiler and it's *always* legal to take its
                      address inside the function. The address becomes illegal after the
                      function returns. The canonical example is:

                      int *f(int a)
                      {
                      return &a;
                      }

                      or the similar

                      int *g(void)
                      {
                      int a;
                      return &a;
                      }

                      It is OK to call these functions *only* if their return value is
                      discarded.

                      Dan
                      --
                      Dan Pop
                      DESY Zeuthen, RZ group
                      Email: Dan.Pop@ifh.de

                      Comment

                      • Martin Dickopp

                        #26
                        Re: Global pointer pointing to locally defined type

                        Andrej Prsa <andrej.prsa@gu est.arnes.si> writes:
                        [color=blue][color=green][color=darkred]
                        >> >> > If this doesn't work, how could I make it work? Do I have to
                        >> >> > allocate memory for this int and copy the original int to that and
                        >> >> > then point value to this newly allocated int?
                        >> >>
                        >> >> That could be one way, yes.
                        >> >
                        >> > Is there any better way you'd suggest?[/color]
                        >>
                        >> I recommend to avoid "global" (file scope) objects whenever possible.
                        >>
                        >> What's the best solution to your problem depends on what your problem
                        >> is. :) If you describe a bit more elaborately what you're actually
                        >> trying to achieve, we might be able to make better suggestions.[/color]
                        >
                        > Sure! I'm making a script language for modeling of eclipsing binaries. I
                        > want to be able to reach a parameter table from all kinds of plug-ins to
                        > this language, thus I have a global table like this:
                        >
                        > typedef struct PHOEBE_paramete r_tag
                        > {
                        > GtkWidget *widget;
                        > char *qualifier;
                        > char *keyword;
                        > char *description;
                        > PHOEBE_type type;
                        > void *valueptr;
                        > } PHOEBE_paramete r_tag;
                        >
                        > PHOEBE_paramete r_tag *PHOEBE_paramet ers;
                        > int PHOEBE_paramete rs_no;
                        >
                        > Here PHOEBE_type is a simple enumeration that defines all types that a
                        > particular argument can be and GtkWidget is a GTK+ widget (GUI related).
                        > PHOEBE_paramete rs is a global array, to which parameters are added by
                        > calling a function:
                        >
                        > void declare_paramet er (char *qualifier, GtkWidget *parent, char *widget,
                        > char *keyword, char *description, ...)
                        >
                        > The variable argument list holds the type and the initial value, e.g.:
                        >
                        > declare_paramet er ("phoebe_name_v alue", PHOEBE, "data_star_name _entry",
                        > "NAME", "Star name", TYPE_STRING, "New star");
                        >
                        > As you may imagine, I want the valueptr of the global PHOEBE_paramete rs[i]
                        > variable to point to whatever value corresponds to the given parameter.
                        > Since it can be int, double, char *, but also an array of those, I hoped a
                        > generic pointer void * would do the trick for me.[/color]

                        You could allocate memory (e.g. using `malloc') and point `valueptr' to
                        it. However, this seems a bit wasteful when you only want to store a
                        single `int' or `double' object. Maybe you could use a union?

                        typedef struct PHOEBE_paramete r_tag {
                        /* ... */
                        PHOEBE_type type;
                        union {
                        int i;
                        double d;
                        char *str;
                        int *i_array;
                        double *d_array;
                        } value;
                        };

                        In your `declare_parame ter' function, you could then allocate memory for
                        strings or arrays, but avoid doing so for `int' or `double' objects:

                        switch (type)
                        {
                        case TYPE_INT:
                        PHOEBE_paramete rs [i].value.i = va_arg (ap, int);
                        break;

                        case TYPE_DOUBLE:
                        PHOEBE_paramete rs [i].value.d = va_arg (ap, double);
                        break;

                        case TYPE_STRING:
                        {
                        const char *const str = va_arg (ap, const char *);

                        PHOEBE_paramete rs [i].value.str = malloc (strlen (str) + 1);
                        if (PHOEBE_paramet ers [i].value.str != NULL)
                        strcpy (PHOEBE_paramet ers [i].value.str, str);
                        else
                        {
                        /* Handle memory allocation failure. */
                        }
                        break;
                        }

                        /* ... */
                        }

                        Martin


                        --
                        ,--. Martin Dickopp, Dresden, Germany ,= ,-_-. =.
                        / ,- ) http://www.zero-based.org/ ((_/)o o(\_))
                        \ `-' `-'(. .)`-'
                        `-. Debian, a variant of the GNU operating system. \_/

                        Comment

                        • Martin Dickopp

                          #27
                          Re: Global pointer pointing to locally defined type

                          Andrej Prsa <andrej.prsa@gu est.arnes.si> writes:
                          [color=blue][color=green][color=darkred]
                          >> >> > If this doesn't work, how could I make it work? Do I have to
                          >> >> > allocate memory for this int and copy the original int to that and
                          >> >> > then point value to this newly allocated int?
                          >> >>
                          >> >> That could be one way, yes.
                          >> >
                          >> > Is there any better way you'd suggest?[/color]
                          >>
                          >> I recommend to avoid "global" (file scope) objects whenever possible.
                          >>
                          >> What's the best solution to your problem depends on what your problem
                          >> is. :) If you describe a bit more elaborately what you're actually
                          >> trying to achieve, we might be able to make better suggestions.[/color]
                          >
                          > Sure! I'm making a script language for modeling of eclipsing binaries. I
                          > want to be able to reach a parameter table from all kinds of plug-ins to
                          > this language, thus I have a global table like this:
                          >
                          > typedef struct PHOEBE_paramete r_tag
                          > {
                          > GtkWidget *widget;
                          > char *qualifier;
                          > char *keyword;
                          > char *description;
                          > PHOEBE_type type;
                          > void *valueptr;
                          > } PHOEBE_paramete r_tag;
                          >
                          > PHOEBE_paramete r_tag *PHOEBE_paramet ers;
                          > int PHOEBE_paramete rs_no;
                          >
                          > Here PHOEBE_type is a simple enumeration that defines all types that a
                          > particular argument can be and GtkWidget is a GTK+ widget (GUI related).
                          > PHOEBE_paramete rs is a global array, to which parameters are added by
                          > calling a function:
                          >
                          > void declare_paramet er (char *qualifier, GtkWidget *parent, char *widget,
                          > char *keyword, char *description, ...)
                          >
                          > The variable argument list holds the type and the initial value, e.g.:
                          >
                          > declare_paramet er ("phoebe_name_v alue", PHOEBE, "data_star_name _entry",
                          > "NAME", "Star name", TYPE_STRING, "New star");
                          >
                          > As you may imagine, I want the valueptr of the global PHOEBE_paramete rs[i]
                          > variable to point to whatever value corresponds to the given parameter.
                          > Since it can be int, double, char *, but also an array of those, I hoped a
                          > generic pointer void * would do the trick for me.[/color]

                          You could allocate memory (e.g. using `malloc') and point `valueptr' to
                          it. However, this seems a bit wasteful when you only want to store a
                          single `int' or `double' object. Maybe you could use a union?

                          typedef struct PHOEBE_paramete r_tag {
                          /* ... */
                          PHOEBE_type type;
                          union {
                          int i;
                          double d;
                          char *str;
                          int *i_array;
                          double *d_array;
                          } value;
                          };

                          In your `declare_parame ter' function, you could then allocate memory for
                          strings or arrays, but avoid doing so for `int' or `double' objects:

                          switch (type)
                          {
                          case TYPE_INT:
                          PHOEBE_paramete rs [i].value.i = va_arg (ap, int);
                          break;

                          case TYPE_DOUBLE:
                          PHOEBE_paramete rs [i].value.d = va_arg (ap, double);
                          break;

                          case TYPE_STRING:
                          {
                          const char *const str = va_arg (ap, const char *);

                          PHOEBE_paramete rs [i].value.str = malloc (strlen (str) + 1);
                          if (PHOEBE_paramet ers [i].value.str != NULL)
                          strcpy (PHOEBE_paramet ers [i].value.str, str);
                          else
                          {
                          /* Handle memory allocation failure. */
                          }
                          break;
                          }

                          /* ... */
                          }

                          Martin


                          --
                          ,--. Martin Dickopp, Dresden, Germany ,= ,-_-. =.
                          / ,- ) http://www.zero-based.org/ ((_/)o o(\_))
                          \ `-' `-'(. .)`-'
                          `-. Debian, a variant of the GNU operating system. \_/

                          Comment

                          • Martin Dickopp

                            #28
                            Re: Global pointer pointing to locally defined type

                            Andrej Prsa <andrej.prsa@gu est.arnes.si> writes:
                            [color=blue]
                            > This brings me to another question: I have read at numerous places
                            > that freeing memory just before the end of the program isn't
                            > necessary, since the OS claims the memory back when the program
                            > execution is over. Is this true?[/color]

                            That depends on the OS. All modern desktop or server systems reclaim
                            the memory automatically, but that's not necessarily the case for
                            embedded devices.

                            If you search the archives of this newsgroup on what's considered better
                            style, you'll find there's no consensus. I personally usually don't
                            bother to free memory immediately before the program terminates, because
                            I'm very sure that the kind of programs I write will never be ported to
                            embedded devices. :)

                            Martin


                            --
                            ,--. Martin Dickopp, Dresden, Germany ,= ,-_-. =.
                            / ,- ) http://www.zero-based.org/ ((_/)o o(\_))
                            \ `-' `-'(. .)`-'
                            `-. Debian, a variant of the GNU operating system. \_/

                            Comment

                            • Martin Dickopp

                              #29
                              Re: Global pointer pointing to locally defined type

                              Andrej Prsa <andrej.prsa@gu est.arnes.si> writes:
                              [color=blue]
                              > This brings me to another question: I have read at numerous places
                              > that freeing memory just before the end of the program isn't
                              > necessary, since the OS claims the memory back when the program
                              > execution is over. Is this true?[/color]

                              That depends on the OS. All modern desktop or server systems reclaim
                              the memory automatically, but that's not necessarily the case for
                              embedded devices.

                              If you search the archives of this newsgroup on what's considered better
                              style, you'll find there's no consensus. I personally usually don't
                              bother to free memory immediately before the program terminates, because
                              I'm very sure that the kind of programs I write will never be ported to
                              embedded devices. :)

                              Martin


                              --
                              ,--. Martin Dickopp, Dresden, Germany ,= ,-_-. =.
                              / ,- ) http://www.zero-based.org/ ((_/)o o(\_))
                              \ `-' `-'(. .)`-'
                              `-. Debian, a variant of the GNU operating system. \_/

                              Comment

                              • Andrej Prsa

                                #30
                                Re: Global pointer pointing to locally defined type

                                Hi, Martin!
                                [color=blue]
                                > You could allocate memory (e.g. using `malloc') and point `valueptr' to
                                > it. However, this seems a bit wasteful when you only want to store a
                                > single `int' or `double' object. Maybe you could use a union?[/color]

                                :) This really makes me smile, because I had exactly these two options in
                                mind. I used mallocs for everything and void * to point to the space, but
                                after your reply I decided to go and change it to union. So now I am using
                                the code you suggested. Thank you very much!

                                Best wishes,

                                Andrej

                                Comment

                                Working...