You do some... weird things in the code you show. To begin with we have the list variable, which should be a simple and plain array instead.
And if the array or its contents should not be modified then you could even create an array whose life-time last the full run-time of the program, using static:
static const char * const *getList() {
static const char * const list[] = { "ABC", "DEF", NULL };
return list;
}
The declaration const char * const list[] declares list as an array (whose size will be deduced from the initialization) of constant pointers to constant characters. That is, the pointers inside list can't be modified, and the string contents itself can't be modified.
If you have other requirements, like being able to modify the strings, then you could still use the definition shown above in my answer, but create a new array to return.
There are a few improvements that can be made to the allocation and copying code as well. For example you could programatically get the size of the array list. I also recommend that you use a simple index loop instead of the pointer arithmetic loop you have now, and with the correct size of the list array the loop will include copying the terminating NULL as well.
All in all it could look something like
static char **getList() {
static const char * const list[] = { "ABC", "DEF", NULL };
// Get the number of elements in the array
size_t list_size = sizeof list / sizeof list[0];
// sizeof *interests is the size of each element we want to allocate
// multiply it by the number of elements we need
char **interests = malloc(sizeof *interests * list_size);
// Do a deep copy of the strings from list
for (size_t i = 0; i < list_size ++i) {
if (list[i] == NULL) {
interests[i] = NULL;
} else {
interests[i] = malloc(strlen(list[i]) + 1); // +1 for the string terminator
strcpy(interests[i], list[i]);
// Or if your system have the strdup function (which is quite common)
// interests[i] = strdup(list[i]);
}
}
return interests;
}
If you don't need a deep copy, then the copying loop could be:
for (size_t i = 0; i < list_size ++i) {
interests[i] = list[i];
}
listthe way you do? Why not a plain simple array of pointers, as inchar *list[] = { "ABC", "DEF", NULL };? And if the array of strings will always be fixed, the strings never modified, you could usestatic const char *list[] = ...;and return that directly.strlendoes not include the string null-terminator. Which means yourstrcpycalls will write out of bounds of your allocated memory, and lead to undefined behavior.interestsas an array of three elements, and use it (when returned) as a null-terminated array, but you never actually copy the terminatingNULLpointer.