For starters the function produces numerous memory leaks. At first a memory is allocated and its address is assigned to a pointer
strings[i-1] = (char*)malloc(9 * sizeof(char));
and then the pointer is reassigned by the address of a string literal
strings[i-1] = "FizzBuzz";
The function can look for example the following way
char ** arr_from_num( size_t n )
{
const char data[] = "FizzBuzz";
char **strings = malloc( n * sizeof( char* ) );
if ( strings != NULL )
{
for ( size_t i = 0; i < n; i++ )
{
strings[i] = malloc( sizeof( data ) );
if ( strings[i] != NULL ) strcpy( strings[i], data );
}
}
return strings;
}
Alternatively the function can be defined the following way
char ** arr_from_num( size_t n, size_t m, const char *dummy )
{
char **strings = calloc( n, sizeof( char* ) );
if ( strings != NULL && m != 0 )
{
for ( size_t i = 0; i < n; i++ )
{
strings[i] = calloc( m, sizeof( char ) );
if ( strings[i] != NULL && dummy != NULL )
{
strncpy( strings[i], dummy, m - 1 );
}
}
}
return strings;
}
Here is a demonstrative program.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char ** arr_from_num( size_t n, size_t m, const char *dummy )
{
char **strings = calloc( n, sizeof( char* ) );
if ( strings != NULL && m != 0 )
{
for ( size_t i = 0; i < n; i++ )
{
strings[i] = calloc( m, sizeof( char ) );
if ( strings[i] != NULL && dummy != NULL )
{
strncpy( strings[i], dummy, m - 1 );
}
}
}
return strings;
}
int main(void)
{
size_t n = 10;
char **strings = arr_from_num( n, n, "FizzBuzz" );
if ( strings != NULL )
{
for ( size_t i = 0; i < n; i++ )
{
printf( "%zu: ", i );
if ( strings[i] == NULL )
{
printf( "%p\n", ( void * )strings[i] );
}
else
{
puts( strings[i] );
}
}
}
if ( strings != NULL )
{
for ( size_t i = 0; i < n; i++ ) free( strings[i] );
}
free( strings );
return 0;
}
The program output is
0: FizzBuzz
1: FizzBuzz
2: FizzBuzz
3: FizzBuzz
4: FizzBuzz
5: FizzBuzz
6: FizzBuzz
7: FizzBuzz
8: FizzBuzz
9: FizzBuzz