amith s bhat
amith s bhat

Reputation: 37

Passing Array Size along with pointer in c

I have a function foo which processes the elements of an array whose size is user defined.

This function needs two parameters (not necessarily two separate arguments, or so do I think) - a pointer to the array and size of the array.

Are the three methods used below to the call the function valid?

int size;                      // Obtained from user 
int arr[size];    

foo(int (*arr)[size]);         // Will size be available as a vairable inside foo ?
foo(int (*arr)[],size);        
foo(int (*arr)[size],size);    // Is the 2nd parameter redundant here ?

Upvotes: 2

Views: 1754

Answers (2)

chux
chux

Reputation: 153468

3 approaches

Pass array and size. (in any order.) b will convert to the type and address of its first element - this becomes a. sizeof b/sizeof b[0] will take on the value of 42 - useful to not repeat 42 all over the place. foo1 receives a pointer the the first element of the array and knows the array element count.

void foo1(int *a, size_t n);
size_t sz = 42;
int b[sz];
foo1(b, sizeof b/sizeof b[0]);

Pass a pointer to an fixed sized array. The address of a fixed sized array is passed to foo2(). foo2() can use (*d)[0] to access the first array element and (*d)[41] for the last element. foo2() does not have to get receive the array element count, because the array element is known and fixed at 42.

void foo2(int (*d)[42]);
int e[42];
foo2(&e);
int f[13];
foo2(&f);  // invalid

Pass the dimensions then a variable-length array. VLA is available in C99 and optionally in C11. Notice that foo3() understands d2 in accessing arr[i][j], but does not know arr outer dimension is d1, even if /* d1 */ was replaced with d1.

void foo3(size_t d1, size_t d2, char  arr[/* d1 */][d2]) {
  char x = 0;
  for (size_t i=0; i<d1; i++) {
    for (size_t j=0; j<d2; j++) {
      arr[i][j] = ++x;
    }
  }
}
void foop(size_t d1, size_t d2, char  arr[/* d1 */][d2]) {
  printf("ptr size:%zu,  sub-array size:%zu, element size:%zu |", 
      sizeof arr, sizeof arr[0], sizeof arr[0][0]);
  for (size_t i=0; i<d1; i++) {
    for (size_t j=0; j<d2; j++) {
      printf(" %d", arr[i][j]);
    }
  }
 printf("\n");
}

int foo2(int (*arr)[42]) {
  printf("%zu\n", sizeof *arr);
  return 0;
}

#define SZ(a)  (sizeof(a)/sizeof((a)[0]))
int main() {
  char  a[2][3];
  char  b[4][5];
  foo3(SZ(a),SZ(a[0]), a);
  foop(SZ(a),SZ(a[0]), a);
  foo3(SZ(b),SZ(b[0]), b);
  foop(SZ(b),SZ(b[0]), b);
}

Sample output

ptr size:4,  sub-array size:3, element size:1 | 1 2 3 4 5 6
ptr size:4,  sub-array size:5, element size:1 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

If a fixed array is needed, the array sizes may be omitted, depending on how the data is passed.

For a variable sized array, the dimensions need to be passed in some fashion.

Arrays may also be passed as a field of a struct/union - not shown.

Upvotes: 0

Atafar
Atafar

Reputation: 717

In C, the size is not part of the array "object". Therefore, idiomatic C code passes the size of an array along with the array itself:

foo(arr, size);

for function

void foo(int arr[], int size);

(in the case of an array of integers).

See for example the main function:

int main(int argc, char *argv[]);

(Note the arguments are reversed here.)

Upvotes: 1

Related Questions