У меня возникла ситуация, которую я никак не могу решить. Это вызывает медленную, но со временем катастрофическую утечку памяти. Я заметил, что, хотя я освобождаю структуру указателей (которую я передал функции), я забыл освободить указатели внутри них, что, согласно valgrind, приводит к утечкам памяти. Я попытался освободить память указателей из функции, но не могу устранить сообщение об ошибке error: request for member 'xxx' in something not a structure or union.
Это краткий обзор моей программы. Я создаю структуру данных, которая содержит переменные, необходимые для многопотоковой функции. Есть основная функция, которой передаются аргументы, и в зависимости от данных она заполняет соответствующую структуру. Затем он запускает поток фактической функции (передавая структуру как указатель void), в котором я беру и воссоздаю фактическую структуру внутри функции. Это код:
void cmd_test(char *sender, char **args, int arg_count) {
char command[1024];
// creates my exec pointer structure
exec_struct *exec = malloc(sizeof(exec_struct));
// adds a thread identifier to a struct to keep track of threads
exec->tID = thread_add(EXEC);
// the first malloc which I don't know how to free
exec->sender = malloc(sizeof(char) * strlen(sender) + 1);
sprintf(exec->sender, "%s", sender);
// move ahead 5 arguments (there will always be 5 or more arguments supplied
// by the calling function)
args += 5;
memset(command, 0, sizeof(command));
// concatenate the remaining arguments into a cstring
while(*args[0]) {
printf("arg: %s\n", *args);
sprintf(command, "%s %s", command, *args);
args++;
}
// the second malloc which I don't know how to free
exec->exec = malloc(sizeof(char) * strlen(command) + 1);
// copy the string to the structure from pointer+1 to end of pointer
// removes a space created from the first iteration of previous loop)
sprintf(exec->exec, "%s", command + 1);
printf("command:%s\n exec:%s\n", command, exec->exec);
//stores an actual thread id into a struct of threads to keep track of
//the actual thread (other one is just to keep track of what type
//of thread is running)
threads[exec->tID].tID = Thread_Start(exec_cmd, exec);
}
Вот как я настроил свою структуру с некоторыми комментариями о том, что происходит. Thread_Start() — это просто функция, которая принимает адрес функции и адрес структуры для передачи функции с нитями. Это функция exec_cmd:
void *exec_cmd(void *param) {
char buf[1024];
FILE *command;
// recreate the structure locally inside the thread
exec_struct exec = *((exec_struct *)param);
// causes the error described
// free(param.exec);
// free(param.sender);
// free the structure memory from the thread creating function.
free(param);
memset(buf,0,1024);
sprintf(buf,"%s",exec.exec);
command = popen(buf,"r");
while(!feof(command)) {
memset(buf,0,1024);
fgets(buf,1024,command);
printf("%s\n", buff);
sleep(1);
}
pclose(command);
// cleans itself up from the tracking structures
thread_remove(EXEC, 0);
// exits cleanly
return NULL;
}
Чтобы устранить ошибку, я попытался создать структуру перед ней, но ошибка все еще сохраняется. Использование оператора -> приводит к ошибке void* deference.
Я также удалил некоторые из функций, таких как проверка того, запущен ли уже поток, и проверка ошибок для уменьшения беспорядка. Обе функции работают в моем приложении (он создает поток, сохраняет его в порядке, отлично передает и создает новую структуру и выполняет переданную команду). Просто я не могу понять, как освободить два вызова malloc, которые я сделал внутри потока. Как я могу решить эту проблему?
while(!feof(command)) {}всегда неправильно. - person wildplasser   schedule 25.12.2012