4
votes

I have the following code:

int main(){
    char **array;
    char a[5];
    int n = 5;

    array = malloc(n *sizeof *array);

    /*Some code to assign array values*/

    test(a, array);

    return 0;
}

int test(char s1, char **s2){
    if(strcmp(s1, s2[0]) != 0)
        return 1;

    return 0;
}

I'm trying to pass char and char pointer array to a function, but the above code results in the following errors and warnings:

temp.c: In function ‘main’:
temp.c:6:5: warning: implicit declaration of function ‘malloc’ [-Wimplicit-function-declaration]
temp.c:6:13: warning: incompatible implicit declaration of built-in function ‘malloc’ [enabled by default]
temp.c:10:5: warning: implicit declaration of function ‘test’ [-Wimplicit-function-declaration]
temp.c: At top level:
temp.c:15:5: error: conflicting types for ‘test’
temp.c:15:1: note: an argument type that has a default promotion can’t match an empty parameter name list declaration
temp.c:10:5: note: previous implicit declaration of ‘test’ was here
temp.c: In function ‘test’:
temp.c:16:5: warning: implicit declaration of function ‘strcmp’ [-Wimplicit-function-declaration]

I'm trying to understand what the problem is.

4
s1 is just a single character. the prototype of test should be int test(char* s1, char **s2)eckes
Always include the errors - they are important, and if we can explain them too you then you'll be able to improve future code yourself.Zeta
Compile with all warnings and treat them as errors (Witg gcc, -Wall --Werror). It would catch the bug in this case.ugoren

4 Answers

7
votes

First of all, you should include the necessary header files. For strcmp you need <string.h>, for malloc <malloc.h>. Also you need to at least declare test before main. If you do this you'll notice the following error:

temp.c: In function ‘test’:
temp.c:20:5: warning: passing argument 1 of ‘strcmp’ makes pointer from integer without a cast [enabled by default]
/usr/include/string.h:143:12: note: expected ‘const char *’ but argument is of type ‘char’

This indicates that test() should have a char * as first argument. All in all your code should look like this:

#include <string.h>      /* for strcmp */
#include <malloc.h>      /* for malloc */

int test(char*,char**);  /* added declaration */    

int main(){
    char **array;
    char a[5];
    int n = 5;

    array = malloc(sizeof(*array));
    array[0] = malloc(n * sizeof(**array));

    /*Some code to assign array values*/

    test(a, array);

    free(*array); /* free the not longer needed memory */
    free(array);

    return 0;
}

int test(char * s1, char **s2){ /* changed to char* */
    if(strcmp(s1, s2[0]) != 0) /* have a look at the comment after the code */
        return 1;

    return 0;
}

Edit

Please notice that strcmp works with null-terminated byte strings. If neither s1 nor s2 contain a null byte the call in test will result in a segmentation fault:

[1]    14940 segmentation fault (core dumped)  ./a.out

Either make sure that both contain a null byte '\0', or use strncmp and change the signature of test:

int test(char * s1, char **s2, unsigned count){
    if(strncmp(s1, s2[0], count) != 0)
        return 1;
    return 0;
}

/* don' forget to change the declaration to 
      int test(char*,char**,unsigned)
   and call it with test(a,array,min(sizeof(a),n))
*/

Also your allocation of memory is wrong. array is a char**. You allocate memory for *array which is itself a char*. You never allocate memory for this specific pointer, you're missing array[0] = malloc(n*sizeof(**array)):

array = malloc(sizeof(*array));
*array = malloc(n * sizeof(**array));
3
votes

Error 1

temp.c:6:13: warning: incompatible implicit declaration of 
built-in function ‘malloc’ [enabled by default]

Did you mean this?

array = malloc(n * sizeof(*array));

Error 2

temp.c:15:5: error: conflicting types for ‘test’
temp.c:15:1: note: an argument type that has a default promotion can’t 
             match an empty     parameter name list declaration
temp.c:10:5: note: previous implicit declaration of ‘test’ was here

You are passing the address of the first element of an array a:

 test(a, array);

So the function signature should be:

int test(char* s1, char** s2)
3
votes

You have several problems. The first is that the prototype is wrong. The data type for a decays to a char pointer when passing to a function, so you need:

int test (char* s1, char** s2) { ... }

However, even when you fix this, the test declaration isn't in scope when you first use it. You should either provide a prototype:

int test (char* s1, char** s2);

before main, or simply move the whole definition (function) to before main.

In addition, don't forget to #include the string.h and stdlib.h headers so that the prototypes for strcmp and malloc are available as well.

1
votes

When you pass an array of char to your function, the argument decays to a pointer. Change your function arguments to

 int test(char* s1, char **s2);
              ^
              ^ 

and your code should at least compile