41

What is the right way to initialize char** ? I get coverity error - Uninitialized pointer read (UNINIT) when trying:

char **values = NULL;

or

char **values = { NULL };
Andreas Fester
  • 36,091
  • 7
  • 95
  • 123
Lior Avramov
  • 695
  • 3
  • 8
  • 13
  • 1
    That's fine for initializing them to be no strings at all; you will still need to point them somewhere valid before you use them (using malloc or similar). – tabstop Jan 09 '14 at 15:02
  • Linux r-mgtswh-130 2.6.18-348.el5 #1 SMP Tue Jan 8 17:53:53 EST 2013 x86_64 x86_64 x86_64 GNU/Linux – Lior Avramov Jan 09 '14 at 15:03
  • 1
    This compiles using gcc. Are you saying this doesn't compile for you, or that you're getting an error when you run your program? – Keeler Jan 09 '14 at 15:14
  • `char ** values` is a pointer to a pointer to `char`, nothing more. `values` is no array of "strings". – alk Jan 09 '14 at 15:46
  • is there a problem to do `char *values[] =` to allocate the array on stack? – V-X Jan 09 '14 at 16:14

3 Answers3

78

This example program illustrates initialization of an array of C strings.

#include <stdio.h>

const char * array[] = {
    "First entry",
    "Second entry",
    "Third entry",
};

#define n_array (sizeof (array) / sizeof (const char *))

int main ()
{
    int i;

    for (i = 0; i < n_array; i++) {
        printf ("%d: %s\n", i, array[i]);
    }
    return 0;
}

It prints out the following:

0: First entry
1: Second entry
2: Third entry
Ebrahimi
  • 1,209
  • 8
  • 15
  • Hi, it works! But i have a question, why i have to use #define n_array here? I have tried with: int n_array, and my app crashes, i'm new to C and dont understand this behavior - #define instead of simple variable int. Thanks. – andymcgregor Nov 25 '17 at 09:38
  • 1
    @teMkaa Using `#define` is just a question of style; personally I wouldn't have done it. Within the `main` function you could easily define another int variable and assign it to `sizeof (array) / sizeof (const char *)`. – Duncan Jones Apr 20 '18 at 07:20
16

Its fine to just do char **strings;, char **strings = NULL, or char **strings = {NULL}

but to initialize it you'd have to use malloc:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main(){
    // allocate space for 5 pointers to strings
    char **strings = (char**)malloc(5*sizeof(char*));
    int i = 0;
    //allocate space for each string
    // here allocate 50 bytes, which is more than enough for the strings
    for(i = 0; i < 5; i++){
        printf("%d\n", i);
        strings[i] = (char*)malloc(50*sizeof(char));
    }
    //assign them all something
    sprintf(strings[0], "bird goes tweet");
    sprintf(strings[1], "mouse goes squeak");
    sprintf(strings[2], "cow goes moo");
    sprintf(strings[3], "frog goes croak");
    sprintf(strings[4], "what does the fox say?");
    // Print it out
    for(i = 0; i < 5; i++){
        printf("Line #%d(length: %lu): %s\n", i, strlen(strings[i]),strings[i]);
    } 
    //Free each string
    for(i = 0; i < 5; i++){
        free(strings[i]);
    }
    //finally release the first string
    free(strings);
    return 0;
}
Nick Beeuwsaert
  • 1,598
  • 1
  • 11
  • 18
11

There is no right way, but you can initialize an array of literals:

char **values = (char *[]){"a", "b", "c"};

or you can allocate each and initialize it:

char **values = malloc(sizeof(char*) * s);
for(...)
{
    values[i] = malloc(sizeof(char) * l);
    //or
    values[i] = "hello";
}
MoonBun
  • 4,322
  • 3
  • 37
  • 69