0

I tried to do this:

char** arr_from_num(int num)
{
    char** strings = (char**)malloc(num*sizeof(char*));
    if (strings == NULL)
        return 0;
    for (int i = 1; i <= num; i++) {
            strings[i-1] = (char*)malloc(9 * sizeof(char));
            strings[i-1] = "FizzBuzz";
    }
    return strings;
}

But the function has a failure in doing this line: char** strings = (char**)malloc(num*sizeof(char*));

How can I do it in other way?

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
dev55555
  • 438
  • 3
  • 13
  • 4
    What makes you think that line is failing? – dbush Jun 02 '20 at 16:15
  • 2
    Except that you [should not cast malloc](https://stackoverflow.com/q/605845/3545273) in C, the shown line seems correct, at least if num has a reasonable value. If a crash occurs there, it is probably because you have invoked Undefined Behaviour elsewhere in your code... – Serge Ballesta Jun 02 '20 at 16:21
  • 2
    Use `strcpy(strings[i-1], "FizzBuzz")` instead of `strings[i-1] = "FizzBuzz"`. – isrnick Jun 02 '20 at 16:26
  • 1
    The `strings[i-1] = "FizzBuzz";` line renders the pointer from the previous line unusable (replacing its value with the address of the string literal). When you later try to `free` that, you'll get a crash (most likely). – Adrian Mole Jun 02 '20 at 16:32
  • As others said, the assignment of the string literal creates a memory leak and might later trigger UndefinedBehavior if you try to modify the string through this pointer. As long as you don't do that, though, this code "works". – Hulk Jun 02 '20 at 16:36

2 Answers2

0

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
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0

An array of strings is basically a 2D array where the first [] in the array syntax shows "how many strings" you have and the 2nd [] shows the length of each.

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    void main()
    {
        char **arr = (char**)malloc(3);
        for (int i = 0;i < 3;i++)
        {
            arr[i] = malloc(sizeof("Fizzbuzz"));
            strcpy(arr[i], "Fizzbuzz");
        }
        //printing
        for (int i = 0;i < 3;i++)
        {
            printf("\n%s", arr[i]);
        }
        free(arr);
     }

You have to allocate memory twice. Once for the number of strings and 2nd for the number of characters in the string. At the end of program you must free memory which you created using malloc function.

Mukund
  • 53
  • 6