bph
bph

Reputation: 11258

Passing arrays as parameters in C

I (think I) understand that you can only retrieve the size of an array (using sizeof) if it is declared at compile time on the stack, e.g.

int my_array[] = {1,2,3};
sizeof(my_array) == 3;

As soon as you start using pointers you lose this length information.

e.g. if you pass a pointer to int as a function parameter to get an int array into a function you can no longer use sizeof() in this way, it will just return the number of bytes used to store a pointer.

Clearly, it is vital to know how long your arrays are.

So which of the following options should I use when passing arrays around?

  1. Pass a pointer and an accompanying length parameter

    int my_func(int *my_array, size_t len_my_array)

  2. Create my own vector struct

    struct vector {
       int *my_array;
       size_t len;
    }
    
    int my_func(struct vector *my_vector)
    
  3. Use someone elses vector implementation. (Is there a default implementation for C as there is for C++?)

  4. Another approach which I've missed?

(I'm currently using the 1st option but its a bit unwieldy and I'm keen to know if this is considered poor programming practice)

Upvotes: 3

Views: 3041

Answers (5)

Jens Gustedt
Jens Gustedt

Reputation: 78903

The simplest way in modern C (aka C99) to my opinion is to use array notation

int my_func(size_t len, int my_array[len]);

which is almost the same as you did but having the size first. The reason to do it in this order is that this scales well to multidimensional arrays

int my_func(size_t n, size_t m, int my_array[n][m]);

you'd then get the index computation correctly inside the function without any additional difficulties.

The only things that you'd have to ensure

  • have the sizes in the list before the arrays, so the sizes are known when you declare the arrays
  • use exactly the same declaration (notation for the dimension and so) in the prototype as you use afterwards for the definition, otherwise you will confuse your users

Upvotes: 3

Cocoadelica
Cocoadelica

Reputation: 3026

It's a bit out there but I've just been reading about arrays and pointers and you could consider using sizeof to determine the total amount of bytes and then divide by the size in bytes of that data type that the array contains to give you the array length...

Upvotes: 0

Jerry Coffin
Jerry Coffin

Reputation: 490108

There is no widely accepted answer, which means about the only way you can depend upon is the first. In particular, unless you write all your code yourself (i.e., never use any libraries) you can pretty much count on the fact that any vector struct you define yourself will differ from anything anybody else uses so at the "boundary" between the code bases, you'll need to your your first method in any case. They may have a vector type of their own that they use internally. You may have one of your own that you use internally -- but where the two talk to each other, they'll have to "unwrap" that type into its individual components.

Upvotes: 1

rerun
rerun

Reputation: 25495

The standard way is to utilize the first approach and pass a pointer and a size especially if you want your code to be reused by others.

Upvotes: 5

Luchian Grigore
Luchian Grigore

Reputation: 258568

One approach that you've missed is putting a terminating element at the end of the array, kind of like '\0' marks the end of a char*.

This and passing the length of the array as a different parameter are the usual ways of doing it.

Upvotes: 7

Related Questions