Tutorial :C: How to correctly declare an array of strings?



Question:

I saw both :

const char*  arr = {"foo", "bar"};  

and

const char*  arr[] = {"foo", "bar"};  

What is the correct and generally standard way?

What is the difference between two?

what is the difference between

   const char**arr = {"foo", "bar"};  

and

    const char* arr[] = {"foo", "bar"};  

and

   const char* * const arr = {"foo", "bar"};      

and

   const char* const * const arr = {"foo", "bar"};  

Sorry for so many questions, just trying to understand it better...


Solution:1

With respect to constness...

const char* constValue = "foo";  constValue = "bar";  constValue[0] = 'x'; // will not work    char* const constPtr = "foo";  constPtr = "bar"; // will not work  constPtr[0] = 'x';    const char* const arr[] = { "foo", "bar", 0 }; // all const  

'const char* const' is is often the best solution for something fully constant. One more optimization would be to also make this static if it is declared in a local scope. The 0 ptr is useful for a sentinel value.


Solution:2

This is not correct as it doesn't have the correct level of indirection.

const char* arr = {"foo", "bar"};  

This is not correct as it's missing an =. It looks a bit like a function definition.

const char* arr[] {"foo", "bar"};  

This is the usual correct form.

const char* arr[] = { "foo", "bar" };  

Edit

You can't initialize a pointer from an aggregate initializer (i.e. { ..., ..., ... } ). You can do both

const char* str1 = "A string";  

and

const char str2[] = "Another string";  

but this is different.

A string literal has type 'array of n char' so can be converted to a pointer whereas an initializer list isn't actually an array, it's just a way to initialize arrays.


Solution:3

There are several approaches. The simplest is to declare an array of arrays of char, like so:

char strs[N][M + 1]; // M is max length of each string  ...  strcpy(strs[i], "foo");  

All the memory for the strings is statically allocated, but the size of each string in the array is fixed, and you have to size for your longest possible string, which may result in some internal fragmentation. All strings are writable.

Another approach is to declare an array of pointers to char:

char *strs[N];  ...  strs[i] = malloc(strlen("bar") + 1);  if (strs[i])     strcpy(strs[i], "bar");   

This way you can allocate as much or as little memory as each string in the array needs, and you can resize your strings if necessary. You can also just point to string literals, but remember that literals may not be writable; i.e., you may not be able to do something like:

strs[j] = "foo";  strs[j][0] = 'b'; // may not be allowed on string literal  

You can dynamically allocate the whole smash:

char **strs = malloc(sizeof *strs * N);  for (i = 0; i < N; i++)    strs[i] = malloc(SIZE + 1);  

This approach allows you to not only resize each string as necessary, but to resize the number of strings. Note that in this case, strs is not an array type, even though it is being treated as an array.

Note that best practices with respect to malloc() differ between C and C++. In C, it's considered bad practice to cast the result of malloc(). For one thing, it's unnecessary, as void pointers are implicitly cast to other object pointer types. For another, it will supress a diagnostic if you forget to #include stdlib.h or otherwise don't have a prototype for malloc() in scope. Remember that if C doesn't see a prototype for a function before it is referenced, it will assume that the function returns int, which cannot be implicitly converted to a pointer type.


Solution:4

Typically, I use dynamic memory if possible here. I find it is simpler to think about pointers than fighting with the array type.

//Allocate pointers for the strings  char **c = (char**)malloc(maxnumofstrs*sizeof(int));  //allocate memory for each string  for(int i = 0; i < maxnumofstrs; i++)  {     c[i] = (char*)malloc(maxwidth);  }  

Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »