Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

This simple C code about string arrays works while it shoudn't and I don't know why

I know there are other ways to solve this like with a calloc but the question here is why does it work while it shouldn’t?

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

void function (char **, char **);

int main () {
  char *list[2], *list1[] = {"word0", "word1", "word2"};

  function(list, list1);
  return 0;
}

void function (char **list, char **list1) {
  for(int i=0; i<2; i++) {
    printf("Insert string\n");
    scanf("%s", (list+i));          //adds 2 strings in list
  }

  for(int i=0; i<2; i++) {
    printf("%s\n", (list+i));       //reads the strings that I just added but if I place * before (list+i) the code crashes
  }

  printf("%s\n", *(list1+1));    //reads the second string of list1 but if I don't place * before (list+1) it reads some weird chars
}

I was trying to better understand pointers and arrays of strings, I expected that it would not work the way it’s written in the comments in the code.
Like why is the "*" needed before (list1+1) and not before (list+i)

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

  char *list[2], *list1[] = {"word0", "word1", "word2"};

This line creates 2 arrays of pointers; the second one contains some words, but the first one is never allocated, so it contains garbage data. You need to allocate memory for list.

void function (char **list, char **list1) {
  for(int i=0; i<2; i++) {
    printf("Insert string\n");
    scanf("%s", (list+i));          //adds 2 strings in list
  }

When you calculate (list+1), you get back a char **, the same type as list. Since list was never assigned a value, this could be anywhere. However, scanf expects a char*, so it’s not writing into an element of list, but writing into list as if list was a string. You need to allocate memory for each element you write into list.

You can do either:

  for(int i=0; i<2; i++) {
    printf("Insert string\n");
    char *newValue = malloc(...);
    list[i] = newValue;
    scanf("%s", list[i]);
  }

or

  for(int i=0; i<2; i++) {
    printf("Insert string\n");
    char *newValue = malloc(...);
    scanf("%s", newValue);
    list[i] = newValue;
  }

.

  for(int i=0; i<2; i++) {
    printf("%s\n", (list+i));       //reads the strings that I just added but if I place * before (list+i) the code crashes
  }

%s expects a char*; in the previous step you wrote into list as if it were a char* so now when you attempt to read it, it works. If you pass it *(list+i), you’re asking printf to "print the string at location ‘input text’".

  printf("%s\n", *(list1+1));    //reads the second string of list1 but if I don't place * before (list+1) it reads some weird chars
}

This is the correct approach, the previous one happens to work because of two errors "canceling" each other.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading