c - 释放指向指针结构的指针

标签 c multithreading memory-management malloc

我遇到了一个似乎无法解决的情况。它会导致缓慢但随着时间的推移而发生灾难性的内存泄漏。我注意到,尽管我正在释放指针结构(我将其传递给函数),但我忘记释放它们自身内部的指针,根据 valgrind 的说法,这会导致内存泄漏。我试图从函数内释放指针的内存,但我似乎无法解决错误消息错误:请求成员'xxx'在不是结构或 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 调用。我该如何解决这个问题?

最佳答案

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 释放之前发生。

关于c - 释放指向指针结构的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14026632/

相关文章:

c - 解释斐波那契代码

objective-c - 多线程 Objective-C 访问器 : GCD vs locks

memory - 我的机器有足够的内存,但是kubernetes无法调度pod并指示内存不足

c - 执行USB/Pendrive中编译的C

c++ - 如何知道消耗了多少堆栈函数?

c - 从函数导出列表

android - 在 GridView 中同步加载图像 - Android

c# - 如何在1秒钟内调用函数200次

ios - 我是否拥有AudioSessionGetProperty返回的对象?

c++ - 使用自定义语言环境注入(inject) stringstream 时出现段错误