You want an array of strings, an array of arrays of characters, a pointer to a pointer to a char.
int length = 4 + groupId_list.nr;
char **id_array= malloc(sizeof(char*) * length);
const char *str1 = "/usr/bin/java";
id_array[0] = malloc(sizeof(char) * (strlen(str1) + 1));
strcpy(id_array[0], str1);
const char *str2 = "-jar";
id_array[1] = malloc(sizeof(char) * (strlen(str2) + 1));
strcpy(id_array[1], str2);
const char *str3 = "pathToFile/jar";
id_array[2] = malloc(sizeof(char) * (strlen(str3) + 1));
strcpy(id_array[2], str3);
for (size_t j = 0; j < groupId_list.nr; ++j) {
id_array[j + 3] = malloc(sizeof(char) * (strlen(groupId_list.items[j].string) + 1));
strcpy(id_array[j + 3], groupId_list.items[j].string);
}
id_array[length - 1] = NULL;
It get's clearer when you use sizeof(*variable)
, which is way more readable and less error prone, and more clearer. Also the parts const char *string = "some string"; malloc(strlen(string) + 1); strcpy
can be simplified with just a call to strdup
.
char **id_array= malloc(sizeof(*id_array) * 4);
id_array[0] = strdup("/usr/bin/java");
id_array[1] = strdup("-jar");
id_array[2] = strdup("pathToFile/jar");
for (int j = 0; j < groupId_list.nr; j++) {
id_array[j + 3] = strdup(groupId_list.items[j].string);
}
id_array[length - 1] = NULL;
Remember to free the memory.
Or depending on your memory ownership model, maybe you don't want to duplicate the memory and just assign pointers. Then just allocate the memory for array of pointers to char and assign pointers. You could allocate memory for string literals on stack.
char **id_array = malloc(sizeof(*id_array) * length);
id_array[0] = (char[]){"/usr/bin/java"};
id_array[1] = (char[]){"-jar"};
id_array[2] = (char[]){"pathToFile/jar"};
for (....) {
id_array[j + 3] = groupId_list.items[j].string;
}
id_array[length - 1] = NULL;
Or you could even carefully read execv specification (see this post) and pass pointers to string literals to execv
and ignore the const
qualifier, as execv
will not modify the array anyway.
# string literals are constant
const char **id_array = malloc(sizeof(*id_array) * length);
id_array[0] = "/usr/bin/java";
id_array[1] = "-jar";
id_array[2] = "pathToFile/jar";
for (....) {
id_array[j + 3] = groupId_list.items[j].string;
}
id_array[length - 1] = NULL;
# explicitly remove the const qualifier, which is safe, because we
# know from the documentation that execv will not modify the array contents
execv(...., (void*)id_array);