0

I've declared:

char array_slave_1[128][128];


int array_length(char *a[]){
    int i = 0;
    while(a[i] != NULL){
        i++;
    }
    return i;
}

    int x = array_length(array_slave_1);

I obtain:

main.c:101:26: warning: passing argument 1 of ‘array_length’ from incompatible pointer type [-Wincompatible-pointer-types]
  101 |     int x = array_length(array_slave_1);
      |                          ^~~~~~~~~~~~~
      |                          |
      |                          char (*)[128]
main.c:16:24: note: expected ‘char **’ but argument is of type ‘char (*)[128]’
   16 | int array_length(char *a[]){

I'm not sure if it is correct the way of passing the argument to the function I declared...I think the the problem is this one, but I don't know how to correctly implement the function array_lenght.

3
  • 1
    Why char array_slave_1[128][128]; and not char * array_slave_1[128]; for string array? Commented Sep 15, 2022 at 10:01
  • 1
    What is "length" on a 2D array??? What are you trying to measure? And how? A global array will initially be full of zeros, and you know the dimensions from the variable's declaration/definition. Functions usually need to be told (via a parameter) about the size(s) of any arrays that they deal with... Commented Sep 15, 2022 at 10:06
  • 1
    It is not possible to implement array_length for the array_slave_1 you have shown. array_slave_1 is an array of arrays, which means each array_slave_1[i] is an array. Since each array_slave_1[i] is an array, whenever it is used an expression other than as the operand of sizeof or the operand of unary &, it will be converted to the address of its first element. That will never be a null pointer. Your loop will eventually overrun the length of the array, and then the behavior is not defined by the C standard. You need to explain the problem further and in more detail. Commented Sep 15, 2022 at 10:11

4 Answers 4

1
char array_slave_1[128][128]

This is 2-dimensional array of char as paramter:

int array_length(char *a[])

This is array of pointers to char (which might be C strings, but could be other char/byte buffers, or single chars too). Except because it is a function parameter, it really is pointer to pointer, so if you are a novice you'd be better off writing what it really is, to avoid getting confused:

int array_length(char **a)

Types of array_slave_1 and a are fundamentally different, and incompatible.


If you want to make your function take the array as parameter, you could do:

int array_length(char a[][128])

which is same as this (note the extra () compared to code in question, they matter!), because array parameters really are pointers, so you have a pointer to one or more char[128] buffers:

int array_length(char (*a)[128])

Then you need a different way to determine the array length, though. Perhaps empty string means end of strings? That's up to you, really.


Alternative is to change your array to be array of pointers:

char *array_slave_1[128]; // 128 pointers to char buffer or C string
// remember that you must allocate the space of each string!
Sign up to request clarification or add additional context in comments.

1 Comment

char a[128][] I think you meant char a[][128]?
0

Perhaps you are just "over complicating" things.

Here is a "best guess" at what you might be trying to achieve (based on allocating room for 128x strings, each up to 127 bytes (plus a null terminator.)

#include <stdio.h>
#include <string.h>

int main() {
    char array_slave_1[ 128 ][ 127 + 1 ]; // notation helps signify this is a string

    strcpy( array_slave_1[ 0 ], "Hello World!" );
    strcpy( array_slave_1[ 1 ], "Foobar" );

    for( int i = 0; i < 2; i++ )
        printf( "'%s' length %d\n", array_slave_1[ i ], strlen( array_slave_1[ i ] ) );

    return 0;
}

Output

'Hello World!' length 12
'Foobar' length 6

strlen() has already been done in the standard C library.

Comments

0
  • char array_slave_1[128][128]; is an array of arrays of char, often called 2D array.
  • char *a[] is an array of pointers to char. It is not compatible with a 2D array.

When an array in C used in most expressions, or when declared as a function parameter, it "decays" into a pointer to it's first element.

  • For a plain char array[x], the first element is char and so it decays to a pointer to char: char*.
  • For an array of arrays char array[x][y], the first element is an array char [y]. So it decays into a pointer to such an array, char (*)[y]. This decay happens to the array you pass as argument, as well as to any 2D array declared as function parameter.

Thus:

void func (char array[128][128]);
...
char array [128][128];
func(array);

Which is 100% equivalent to:

void func (char (*array)[128]);
...
char array [128][128];
char(*ptr)[128] = array;
func(array);

So for accepting a 2D array, you may declare the function using either of the above equivalent forms, though the latter is less readable. The most generic and readable form of all might however be a variable-length array:

void func (size_t x, size_t y, char array[x][y]);

Please also note that while(a[i] != NULL) will only work for arrays of pointers, where the last pointer was assigned to NULL, a so-called "sentinel value". You cannot use this unless you keep the function as char* arr[n] and then pass an array of pointers as argument instead.

Comments

0

How to pass a string array to a function?

That depends on what you mean by "string array", because it turns out that there are, sort of, two completely different types of "string" in C. Formally, a string is an array of characters. But since arrays almost always decay into pointers when you use them, it is extremely common to think about char * — that is, pointer-to-char — as also being a "string type" in C.

char array_slave_1[128][128];

This is an array of arrays of char. So it is usefully an array of strings, using the array definition of "string". It does have the limitation that none of the strings it contains can ever be longer than 127 characters.

int array_length(char *a[]) { ...

This function accepts an array of pointers to char. So it is also usefully an array of strings, using the pointer definition of "string". It is further apparent that you are trying to use an array of pointers here given that you are looking for a NULL pointer to mark the end of the array.

But! In this case, the two different types of "array of string" are not compatible! An array of arrays is completely different from an array of pointers. There are no automatic conversions that will let you start with one, and treat it as if it was the other.

(This is by contrast to the situation with simple, single strings, since the array-decay-to-pointer rule always lets you treat an array-string as if it were a pointer-string.)

Your best bet is probably to change

char array_slave_1[128][128];

to

char *array_slave_1[128];

Now you have an array of 128 pointer-strings. This will be compatible with your array_length function, and it will remove the limitation on the lengths of the individual strings in the array. On the other hand, you will need to change any code you have for initializing and manipulating the string in array_slave_1: Some of that code may still be fine, but anything that involves something like strcpy(array_slave_1[i], ...) will have to change. Depending on your needs, you may also need to call malloc to allocate space for each element in the array to point to.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.