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)
CodePudding user response:
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.