どうしても解決できない状況があります。ゆっくりと、しかし時間が経つにつれて悲惨なメモリリークを引き起こしています。ポインターの構造 (関数に渡したもの) を解放しているにもかかわらず、それらの内部のポインターを解放するのを忘れていたことに気付きました。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
エラーが発生します。
また、スレッドが既に実行されているかどうかを確認するチェックや、煩雑さを軽減するためのエラー チェックなど、関数からいくつかの大部分を削除しました。関数は両方とも私のアプリケーションで機能します(スレッドを作成して正常に保存し、新しい構造を完全に渡して作成し、渡されたコマンドを実行しています)。スレッド内から行った 2 つの malloc 呼び出しを解放する方法がわかりません。この問題を解決するにはどうすればよいですか?