1

I needed to test something and programmed this little bit of code(shown below). I can't understand why the first print works and the second doesn't. The output of this program is just

    this prints

but it should be

    this prints
    this doesn't print i: 1

Here's the code:

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

int cmp(char *str) {
    char *z[1];
    strcpy(*z, "z");
    int a;

    a = strcmp(str, *z);

    return a;
}

int main() {
    int i;
    char *name[1];
    printf("this prints\n");

    strcpy(*name, "y");
    i = cmp(*name);
    printf("this doesn't print i:%d", i);
    return 0;
}
chqrlie
  • 131,814
  • 10
  • 121
  • 189

2 Answers2

3
char *z[1]; // this is an array of pointer
strcpy(*z, "z"); // you have to allocate at least 2 bytes for *z

// and
char *name[1];
strcpy(*name, "y"); // you have to allocate at least 2 bytes for *name also

You did not allocate for the pointer in array z and name.

Your cmp function looks weird. If you want to compare string with "z", you can just do:

int cmp(char *str){
   return strcmp(str, "z");
}

You do not need to use char *name[1], just char *name = malloc(SIZE+1); or char name[SIZE+1] (SIZE is length of string that you want to compare) is enough.

Hitokiri
  • 3,607
  • 1
  • 9
  • 29
  • This answer explains the "why" without just fixing the problem, which is good. What the question exposes is that there's a subtle difference between arrays of characters (fixed sizes) and strings (null terminated) and using pointers (whether they are to an array, static string, or allocated memory). This short resource will fill in the knowledge gap, https://www.cs.bu.edu/teaching/cpp/string/array-vs-ptr/. – Walt Stoneburner May 24 '20 at 14:38
  • Your link was really helpful but I thought I should point out that it's written for C++, as it uses the 'new' keyword. According to the Cameron Skinner 'new' is a C++ keyword https://stackoverflow.com/questions/8595560/plain-c-using-new-keyword – GigiNicaragua May 25 '20 at 21:36
  • @GigiNicaragua, i think he just wants to show you some definition of C string (array of characters, pointer to character). You can ignore `new` keyword. OT, does my answer solve your problem. If yes, you can click on the check mark ("V") of the answer to accept it – Hitokiri May 25 '20 at 22:12
  • @Hitokiri Done. Your answer was really helpful aswell, thanks! What does OT mean? – GigiNicaragua May 26 '20 at 19:06
  • It means other thing :)) – Hitokiri May 26 '20 at 19:10
1

char *z[1]; and char *name[]

  1. Both name and z are not arrays of char. They are both an array of one pointer to char.

  2. Both pointers name[1] and z[1] point to no valid memory, thus dereferencing it and attempting to store a string to that undefined memory by using strcpy(*name, "y"); and strcpy(*z, "z"); and invokes undefined behavior. - What you need is an array of char for both, name and z.

  3. For storing a string you need one element to store the string-terminating null character.

Use char z[2] and name[2], if you only want to have strings contained of one single character.


BTW, Your code is a little bit complicate handled. You do not to use strings if you want to store and compare only single characters. It could be simplified as:

#include <stdio.h>

int main (void) {

    char name = 'y';
    printf("In name is the character: '%c'\n", name);

    printf("Is the character 'z' in 'name'? %d", name == 'z');
    return 0;
}

Output:

In name is the character: 'y'
Is the character 'z' in 'name'? 0

Where 0 means false and 1 signifies true.


Side Note:

You didn´t need to #include <stdlib.h> at any point of time.