C 将指针释放到指针结构
我的处境似乎无法解决。它会导致缓慢但随着时间的推移灾难性的内存泄漏。我注意到,尽管我正在释放指针结构(我将其传递给函数),但我忘记了释放它们内部的指针,根据valgrind的说法,这会导致内存泄漏。我试图从函数中释放指针的内存,但似乎无法解决错误消息C 将指针释放到指针结构,c,multithreading,memory-management,malloc,C,Multithreading,Memory Management,Malloc,我的处境似乎无法解决。它会导致缓慢但随着时间的推移灾难性的内存泄漏。我注意到,尽管我正在释放指针结构(我将其传递给函数),但我忘记了释放它们内部的指针,根据valgrind的说法,这会导致内存泄漏。我试图从函数中释放指针的内存,但似乎无法解决错误消息错误:请求非结构或联合中的成员“xxx” 这是我的课程的简短概述。我正在创建一个数据结构,它保存线程函数所需的变量。有一个main函数,参数被传递到该函数,并且取决于它在适当的结构中填充的数据。然后它启动一个实际函数的线程(将结构作为空指针传递),在
错误:请求非结构或联合中的成员“xxx”
这是我的课程的简短概述。我正在创建一个数据结构,它保存线程函数所需的变量。有一个main函数,参数被传递到该函数,并且取决于它在适当的结构中填充的数据。然后它启动一个实际函数的线程(将结构作为空指针传递),在该线程中,我获取并重新创建函数内部的实际结构。代码如下:
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\u Start()
只是一个函数,它接受传递给线程函数的函数地址和结构地址。这是exec\u 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*遵从性
错误
我还从函数中删除了一些功能,比如检查线程是否已经在运行,以及错误检查以减少混乱。这两个函数都在我的应用程序中工作(它创建线程并将其很好地存储,它完美地传递和创建新结构,并且它正在执行传递的命令)。只是我不知道如何释放线程内部的两个malloc调用。我如何解决这个问题
exec_struct exec = *((exec_struct *)param);
//free(param.exec);
//free(param.sender);
param是传入的void*
。您的结构副本称为exec
你的意思可能是:
free(exec.exec);
free(exec.sender);
但是,请注意,稍后在同一函数中立即访问exec.exec
。如果你已经释放了它,你就不能这么做。复制结构并不意味着您已经复制了指针指向的内存
这一行:
sprintf(buf,"%s",exec.exec);
需要在exec.exec释放之前发生。一般原则是从结构中的“最深”层次开始,然后逐步向上。永远不要让“上层”的东西被释放,直到里面的所有东西都被释放。换句话说,使用与调用malloc相反的顺序 我真的不明白这样做的意义:
exec_struct exec = *((exec_struct *)param);
我只想复制原始指针:
exec_struct *exec = (exec_struct *)param;
然后
当然,在使用完exec结构之前,不应该执行任何释放操作。
而(!feof(command)){}
总是错误的。我试图释放我在第一个函数中删除的原始结构。我将指针从我传递的结构传递到我制作的新副本,而我只是通过free(param)
释放旧数据结构,这到底是怎么回事?如果是这样的话,如果我free(param)
然后在函数末尾free(exec.xxxx)
所有东西都会被释放吗?如果是这样的话,现在对我来说是有意义的。如果不是的话,请你再解释一下。基本上,是的exec
是结构的一个副本,它将包括指向您malloc的内存的指针。因此,您可以释放param
,因为您不再引用该参数,但您需要保留exec.**,直到您完成这些参数,然后您也可以释放这些参数。谢谢您的帮助。尽管我再次运行valgrind,并且每次创建线程时,它都返回为:1个块中的136字节可能在丢失记录4中丢失,共4个==11079==at 0x402425F:calloc(vg_replace_malloc.c:467)==11079==by 0x4010D2B:_dl_allocate_tls(dl tls.c:300)==11079==by 0x40432E2:pthread\u create@@GLIBC 2.1(allocatestack.c:561)==11079==by 0x80491AB:Thread\u Start(project.c:217)我如何才能知道这是不是真的以及为什么会发生这种情况。我没有对线程进行任何malloc调用。所有其他泄漏都已修复
free(exec->sender);
free(exec->command);
free(exec);