In this declaration
char **s = calloc(n, 10 * (sizeof(char) + 1));
you allocated a memory the address of which is assigned to the pointer s
. The memory was zero-initialized due to calling the function calloc
.
So in this statement
fgets(*(s + i), 10 * (sizeof(char) + 1), stdin);
the pointer s
is dereferenced and either is a null pointer (because the pointed memory was zero-initialized) or has an indeterminate value if the expression s + i
points outside the allocated memory.
You need to allocate an array of pointers of the type char *
and assign to each pointer the address of an allocated array of characters.
Also in general you should check the return value of a call of calloc
or malloc
.
There is another problem with your code. After the call of scanf
scanf("%i", &n); //number of strings being inputted
the input buffer contains the new line character '\n'
that will be read by the following call of fgets
. So the first call of fgets
will read in fact an empty string.
Another problem is that you should remove the new line character that can be appended to the read string by fgets
. For example some read string can contain the new .line character while others can be without it depending on how many characters the user typed.
If you want to write the program without using the subscript operator with pointers then it can look for example the following way.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
size_t n = 0;
if ( scanf( "%zu", &n ) == 1 )
{
scanf( "%*[^\n]" );
scanf( "%*c" );
}
char **s = NULL;
if ( n != 0 ) s = calloc( n, sizeof( char * ) );
if ( s != NULL )
{
size_t len = 11;
size_t m = 0;
while ( m < n && ( *( s + m ) = malloc( len * sizeof( char ) ) ) != NULL ) m++;
size_t i = 0;
while ( i < m && fgets( *( s + i ), len, stdin ) != NULL ) i++;
m = i;
for ( i = 0; i < m; i++ ) //print the strings
{
( *( s + i ) )[ strcspn( *( s + i ), "\n" )] = '\0';
// or without the subscript operator
// *( *( s + i ) + strcspn( *( s + i ), "\n" ) ) = '\0';
puts( *( s + i ) );
}
for ( i = 0; i < n; i++ ) free( *( s + i ) );
}
free( s );
return 0;
}
The program output might look like
10
one
two
three
four
five
six
seven
eight
nine
ten
one
two
three
four
five
six
seven
eight
nine
ten