How to pass a pointer to an unknown-size array?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • nospam@nospam.com

    How to pass a pointer to an unknown-size array?


    Hello!

    I can pass a "pointer to a double" to a function that accepts
    double*, like this:

    int func(double* var) {
    *var=1.0;
    ...
    }

    double var;

    n=func(&var);

    ---

    Now I want to pass a pointer to an array of doubles, the size
    of the array must not be fixed though:

    int func(double[]* array) {
    int index;
    index=3;
    array[index]=1.0;
    ...
    }

    double array[100];

    n=func(&array);

    with the above code the compiler gives me an error. The only
    solution that I found so far is this very inelegant one:

    int func(void* array) {
    int index;
    index=3;
    *((double*)(arr ay)+index)=1.0;
    ...
    }

    double array[100];

    n=func(&array);

    ---

    There must be a cleaner way.. but what is it?

    I am interested in both C and "C++ only" solutions.

    Thanks!
    Mike

  • Espen Suenson

    #2
    Re: How to pass a pointer to an unknown-size array?

    nospam@nospam.c om wrote:
    [color=blue]
    > Now I want to pass a pointer to an array of doubles, the size
    > of the array must not be fixed though:
    >
    > int func(double[]* array) {
    > int index;
    > index=3;
    > array[index]=1.0;
    > ...
    > }
    >
    > double array[100];
    >
    > n=func(&array);[/color]

    The standard way of doing it is like this:

    int func(double* array){
    array[3]=1.0;
    ...
    }

    double array[100];

    n=func(array);

    The last line is equivalent to this:

    n=func(&array[0]);

    The reason is that the name of an array is a synonym for the location of
    the initial element.

    Espen
    --
    Numbers are the free creation of the human mind.
    Julius Wilhelm Richard Dedekind

    Comment

    • Jonathan Bartlett

      #3
      Re: How to pass a pointer to an unknown-size array?

      > Now I want to pass a pointer to an array of doubles, the size[color=blue]
      > of the array must not be fixed though:[/color]

      Try this:

      int func(double *array, int num_elements)
      {
      int i;
      for(i = 0; i < num_elements; i++)
      {
      array[i] = 1.0;
      }
      }

      int main()
      {
      double array[100];
      func(array, 100);
      }

      The single pointer will point to the first element of the array. You do
      not need double indirection. You need to explicitly pass the size of
      the array, as C does not keep that information store.

      Jon
      ----
      Learn to program using Linux assembly language

      Comment

      • john_bode@my-deja.com

        #4
        Re: How to pass a pointer to an unknown-size array?



        nospam@nospam.c om wrote:[color=blue]
        > Hello!
        >
        > I can pass a "pointer to a double" to a function that accepts
        > double*, like this:
        >
        > int func(double* var) {
        > *var=1.0;
        > ...
        > }
        >
        > double var;
        >
        > n=func(&var);
        >
        > ---
        >
        > Now I want to pass a pointer to an array of doubles, the size
        > of the array must not be fixed though:
        >
        > int func(double[]* array) {
        > int index;
        > index=3;
        > array[index]=1.0;
        > ...
        > }
        >
        > double array[100];
        >
        > n=func(&array);
        >
        > with the above code the compiler gives me an error. The only
        > solution that I found so far is this very inelegant one:
        >
        > int func(void* array) {
        > int index;
        > index=3;
        > *((double*)(arr ay)+index)=1.0;
        > ...
        > }
        >
        > double array[100];
        >
        > n=func(&array);
        >
        > ---
        >
        > There must be a cleaner way.. but what is it?
        >
        > I am interested in both C and "C++ only" solutions.
        >
        > Thanks!
        > Mike[/color]

        int func(double *array, size_t arrsize)
        {
        int index = 3;
        if (index < arrsize)
        {
        array[index]=1.0;
        }
        ...
        }

        ....

        double array[100];
        int n = func(array, sizeof array);
        ....

        Remember that in C, the subscripting operation a[i] is *defined* as
        *(a+i). Therefore, in *most* expression contexts (sizeof() being one
        of two exceptions IINM), the type of a is converted from array of T to
        pointer to T, and its value is set to the address of the first element
        in the array (&a[0]), so the expression *(a+i) yields the correct
        result. Because of this conversion, when you pass an array as a
        parameter to a function, what you wind up passing is a pointer to the
        base type, and its value is the address of the first element (this is
        why I didn't use the address operator & in the function call above).

        If you need to know the size of the array in the function, you need to
        specify the array size as a separate parameter; a pointer doesn't know
        the size of the chunk of memory it's pointing to.

        If you wished to pass a pointer to the array object (not just a pointer
        to the first element), the code would look like this:

        int func(double (*array)[100]) // size must match original
        {
        int index=3;
        (*array)[index] = 1.0;
        ...
        }

        ....
        double array[100];
        n = func(&array);

        This time, we are passing a pointer to a 100-element array of double.
        Since 100-element array of double is a distinct type, this approach
        won't work for arrays of different sizes.

        Comment

        • Aaron Gage

          #5
          Re: How to pass a pointer to an unknown-size array?

          nospam@nospam.c om wrote:[color=blue]
          > Hello!
          >
          > I can pass a "pointer to a double" to a function that accepts
          > double*, like this:
          >
          > int func(double* var) {
          > *var=1.0;
          > ...
          > }
          >
          > double var;
          >
          > n=func(&var);
          >
          > ---
          >
          > Now I want to pass a pointer to an array of doubles, the size
          > of the array must not be fixed though:
          >
          > int func(double[]* array) {
          > int index;
          > index=3;
          > array[index]=1.0;
          > ...
          > }
          >
          > double array[100];
          >
          > n=func(&array);
          >
          > with the above code the compiler gives me an error. The only
          > solution that I found so far is this very inelegant one:
          >
          > int func(void* array) {
          > int index;
          > index=3;
          > *((double*)(arr ay)+index)=1.0;
          > ...
          > }
          >
          > double array[100];
          >
          > n=func(&array);
          >
          > ---
          >
          > There must be a cleaner way.. but what is it?
          >
          > I am interested in both C and "C++ only" solutions.
          >
          > Thanks!
          > Mike
          >[/color]

          To pass a pointer to the array, not to the first element do:

          int func(double **array) { or func(double **array, unsigned size) }

          then you can code:
          double array[100];
          n = func(&array); { or n = func(&array, 100); }

          But why do you require a pointer to the array, and not pointer to first
          element??

          Comment

          • doob

            #6
            Re: How to pass a pointer to an unknown-size array?

            For a detailed discussion on passing arrays to funtions in C, I
            recommend you refer to Expert C Programming by Peter van der Linden
            which has an entire chapter discussing arrays & their relationships
            with pointers. This will certainly clarify any issues you may have.

            Comment

            • john_bode@my-deja.com

              #7
              Re: How to pass a pointer to an unknown-size array?



              Aaron Gage wrote:[color=blue]
              > nospam@nospam.c om wrote:[color=green]
              > > Hello!
              > >
              > > I can pass a "pointer to a double" to a function that accepts
              > > double*, like this:
              > >[/color][/color]

              [snip]
              [color=blue]
              >
              > To pass a pointer to the array, not to the first element do:
              >
              > int func(double **array) { or func(double **array, unsigned size) }
              >
              > then you can code:
              > double array[100];
              > n = func(&array); { or n = func(&array, 100); }
              >[/color]

              This is not correct. The type of &array is "pointer to 100-element
              array of double", *not* "pointer to pointer to double". The correct
              prototype is

              int func(double (*array)[100]);

              You would pass a pointer to pointer to double if you were passing a
              pointer to the first element of a 2-d array of double, like so:

              double array[5][10];
              n = func(array, 5, 10);

              int func(double **a, size_t d0, size_t d1);

              Since the type "100-element array of double" is a distinct type from
              "101-element array of double", the type "pointer to 100-element array
              of double" is a distinct type from "pointer to 101-element array of
              double", so you don't have to pass the size as a separate parameter;
              the array size is specified in the prototype:

              int func(double (*array)[100])
              {
              size_t count = sizeof *array / sizeof (*array)[0];
              ...
              }

              This means func() can *only* be called with 100-element arrays of
              double.

              However, this defeats the OP's purpose, which is to be able to deal
              with arrays of any size; this is why he needs to pass a pointer to the
              first element and the array size as parameters.

              Comment

              • john_bode@my-deja.com

                #8
                Re: How to pass a pointer to an unknown-size array?



                john_bode@my-deja.com wrote:

                [snip]
                [color=blue]
                > double array[100];
                > int n = func(array, sizeof array);[/color]

                Dammit, that's a bug. That last line *should* read:

                int n = func(array, sizeof array / sizeof array[0]);

                Back to your regularly scheduled programming...

                Comment

                • E. Robert Tisdale

                  #9
                  Re: How to pass a pointer to an unknown-size array?

                  > cat main.c
                  #include <stdlib.h>
                  #include <stdio.h>

                  int doubleArray_fpr intf( // total number of characters
                  FILE* fp, // file pointer
                  const
                  char* format, // format for elements
                  size_t columns, // number of columns
                  const
                  size_t n, // array size
                  const
                  double array[n] // the array to be printed
                  ) {
                  columns = (0 < columns)? columns: 4;
                  int total = 0; // total number of characters
                  for (size_t j = 0; j < n; ++j) {
                  int characters = fprintf(fp, " ");
                  if (0 < characters) {
                  total += characters;
                  characters = fprintf(fp, format, array[j]);
                  if (0 < characters) {
                  total += characters;
                  size_t k = j + 1;
                  if (0 == k%columns && k < n) {
                  characters = fprintf(fp, "\n");
                  if (0 < characters) {
                  total += characters;
                  }
                  else {
                  total = characters;
                  break;
                  }
                  }
                  }
                  else {
                  total = characters;
                  break;
                  }
                  }
                  else {
                  total = characters;
                  break;
                  }
                  }
                  return total;
                  }

                  int main(int argc, char* argv[]) {
                  const
                  size_t n = 10;
                  double array[n];
                  for (size_t j = 0; j < n; ++j) {
                  array[j] = j;
                  }

                  doubleArray_fpr intf(stdout, "%g", 5, n, array);
                  fprintf(stdout, "\n");

                  return 0;
                  }
                  [color=blue]
                  > gcc -Wall -std=c99 -pedantic -o main main.c
                  > ./main[/color]
                  0 1 2 3 4
                  5 6 7 8 9

                  Comment

                  • Emmanuel Delahaye

                    #10
                    Re: How to pass a pointer to an unknown-size array?

                    Aaron Gage wrote on 27/05/05 :[color=blue][color=green]
                    >> double array[100];[/color][/color]
                    [color=blue]
                    > To pass a pointer to the array, not to the first element do:
                    >
                    > int func(double **array) { or func(double **array, unsigned size) }[/color]

                    Nope. You meant

                    int func(double (*array)[100])

                    --
                    Emmanuel
                    The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
                    The C-library: http://www.dinkumware.com/refxc.html

                    "C is a sharp tool"

                    Comment

                    • Tim Rentsch

                      #11
                      Re: How to pass a pointer to an unknown-size array?

                      john_bode@my-deja.com writes:
                      [color=blue]
                      > Aaron Gage wrote:[color=green]
                      > > nospam@nospam.c om wrote:[color=darkred]
                      > > > Hello!
                      > > >
                      > > > I can pass a "pointer to a double" to a function that accepts
                      > > > double*, like this:
                      > > >[/color][/color]
                      >
                      > [snip]
                      >[color=green]
                      > >
                      > > To pass a pointer to the array, not to the first element do:
                      > >
                      > > int func(double **array) { or func(double **array, unsigned size) }
                      > >
                      > > then you can code:
                      > > double array[100];
                      > > n = func(&array); { or n = func(&array, 100); }
                      > >[/color]
                      >
                      > This is not correct. The type of &array is "pointer to 100-element
                      > array of double", *not* "pointer to pointer to double". The correct
                      > prototype is
                      >
                      > int func(double (*array)[100]);[/color]

                      That's one correct prototype. Another one is:

                      int func( double (*array)[] );

                      Or, perhaps more usefully:

                      int func( double (*array)[], unsigned index_limit );

                      This allows arrays of all sizes to be passed. And, it offers a
                      potentially useful check, in that only arrays can be passed. So, if
                      we have:

                      #define FUNC(a) ( func( &(a), sizeof( a ) / sizeof *(a) ) )

                      then FUNC will work on arrays, but pointers will get (are required to
                      get?) a diagnostic about "incompatib le types".

                      Comment

                      Working...