You indeed have a memory leak in your addcommand function, at this line:
srclist -> list[srclist -> len] -> function = malloc(sizeof(void*));
The reason is that the pointer that you obtained from malloc stored into function gets overwritten later by the following line:
srclist -> list[srclist -> len] -> function = fun;
After this point, the pointer to the memory returned by malloc is lost and you cannot free it, hence the memory leak.
In fact, you don't need to malloc anything for that function, since the memory for the function pointer was already allocated by this line:
srclist -> list[srclist -> len] = malloc(sizeof(command));
The command struct already contains the memory for the field function. So you can just set function to the fun pointer.
Note also that the fun is not a void pointer, but rather a function pointer, so you should declare it as void (*fun)(command_list *) instead of void *fun.
Another comment: why do you keep a command** list instead of command* list? You are currently allocating memory twice, once for the command * pointer, and then for the actual command struct. A simpler (and less memory-hungry) solution would be to have:
typedef struct
{
command* list; // changed command **list to command *list
int len;
command_history* history;
} command_list;
and adding a new command in the list would look like:
void addcommand(char* str, void (*fun)(command_list*), command_list* srclist)
{
printdebug("Adding command \"%s\" pointing to function at %p in command list located at %p... ", str, fun, srclist);
srclist -> list = realloc(srclist -> list, sizeof(command) * (srclist -> len + 1));
srclist -> list[srclist -> len] -> alias = malloc(sizeof(char) * (strlen(str) + 1));
memcpy(srclist -> list[srclist -> len] -> alias, str, sizeof(char) * (strlen(str) + 1)); // |
srclist -> list[srclist -> len] -> function = fun; // <|
srclist -> len++;
printdebug("Command added.\n");
}
Additionally, you should check the return value for malloc and realloc. They may return a NULL pointer if there is insufficient memory, and the following code that dereferences these pointers will cause a segmentation fault and crash the program.