I know the problem seems weird but I need to initialize (or convert) a constant string array in C.
The problem is that the string array is initialized dynamically but an API function I'd like to use only accepts constant string arrays.
I know that this works:
const char *const arr[] = { "test" };
But again: Since I don't know how many items the array will have nor I know the content pre runtime, I can't initialize the array that way.
So of course this won't work
const char *const arr[1];
arr[1] = "test"; // won't work
My question is: Is it possible to convert somehow the dynamically string array to a read-only one? Or is there a way to initialize the array dynamically once?
EDIT 1: My exact problem
int len = 8;
const char *names1[8] = {"test0","test1","test2","test3","test4","test5","test6","test7" }; // not what I'm looking for
const char *names2[len];
const char *names3[len];
// nearly what I'm looking for
for(int j=0; j<len; j++) {
names2[j] = "test";
}
// exactly what I'm looking for
for(int j=0; j<len; j++) {
sprintf(names3[j],"%s%d","test",j); // discards 'const' qualifier
}
// ...
Cudd_DumpDot(gbm, 1, ddnodearray, names1, NULL, outfile);
Cudd_DumpDot(gbm, 1, ddnodearray, names2, NULL, outfile);
Cudd_DumpDot(gbm, 1, ddnodearray, names3, NULL, outfile); // won't work
Okay this is my progress so far.
The method with names2 is indeed working but I'd like to use sprintf (as shown with names3) since I need to append j in this case. And this would wound the const qualifier.
Technically there is nothing stopping you from casting the pointer to (char *) and then setting the elements with memset or alike.
However this invokes undefined behaviour since the compiler can put it into read-only marked memory.
Excerpt from an answer on another SO question:
The const qualifier is an instruction to the compiler to reject code that attempts to modify that object directly; attempts to modify the object indirectly (as you do in the second code snippet) results in undefined behavior, meaning any result is possible.
There is no way (without invoking UB) to change a constant after its initialisation - so don't do that.
UPDATE As @chux pointed out in the comments it is indeed possible to dynamically initialize local variables.
an API function I'd like to use only accepts constant string arrays.
That's no reason to pass an array of constant pointers ... the conversion to const (in this case constant array elements) is allowed (and even implicit), so the following (nonsensical) code compiles just fine:
const char *test(const char *const *foo)
{
return foo[0];
}
int main(void)
{
const char *arr[10];
arr[0] = "Foobar";
const char *x = test(arr);
return (int) *x;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With