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)
>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.