pthread_cleanup 没有正确调用 free()

pthread_cleanup not correctly calling free()

我遇到了线程内存泄漏问题。当线程被取消或以其他方式正常退出时,我想释放 dat 数组和 buff 数组。我的问题似乎是我的 pthread_cleanup 堆栈中的免费调用没有执行。我知道我的堆栈在工作,因为我的其他清理处理程序功能在工作。对这里发生的事情有任何了解吗?我的一个想法是创建另一个清理处理函数来释放东西,但这似乎效率不高。

static void *dat_col(void *arg) {
  struct args *prof = (struct args *)arg;
  char *dat = NULL;
  char *buff = NULL;
  time_t start_t = 0;
  time_t cur_t = 0;
  int ret = 0;
  
  struct timespec timeout;
  clock_gettime(CLOCK_REALTIME, &timeout);
  timeout.tv_sec += (60 * prof->interval);
  pthread_cleanup_push(cleanup_handler, &prof->fc);
  pthread_cleanup_push(free, (void *) dat);
  pthread_cleanup_push(free, (void *) buff);

  dat = malloc(50 * prof->points);
  if (dat == NULL) {
    perror("memory error");
    goto fail;
  }
  memset(dat, 0, 50 * prof->points);
  
  buff = malloc(2);
  if (buff == NULL) {
    perror("memory error");
    goto fail;
  }
  memset(buff, 0, 2);
  

  time(&start_t);

  ret = write_port(prof->fd, "OPC?;PRES;\r", 11);
  if (ret < 0)
    goto fail;
  ret = read_port(prof->fd, buff, 2);
  if (ret < 0) {
    goto fail;
  }

  switch (prof->time_flag) {
  case 0:
    while (!exit_flag) {
      pthread_testcancel();
      ret = get_DATA(prof->fd, dat, prof->points, prof->chan, prof->fstar,
                     prof->fstop, &prof->fc);
      if (ret < 0)
        goto fail;
      memset(dat, 0, 50*prof->points);
      pthread_mutex_lock(&wait);
      pthread_cond_timedwait(&cond, &wait, &timeout);
      pthread_mutex_unlock(&wait);
      timeout.tv_sec += (60 * prof->interval);
    }
    break;
  case 1:
    while ((difftime(start_t, cur_t) < (60 * prof->testtime)) && (!(exit_flag))) {
      pthread_testcancel();
      ret = get_DATA(prof->fd, dat, prof->points, prof->chan, prof->fstar,
                     prof->fstop, &prof->fc);
      if (ret < 0)
        goto fail;
      memset(dat, 0, 50*prof->points);
      pthread_mutex_lock(&wait);
      pthread_cond_timedwait(&cond, &wait, &timeout);
      pthread_mutex_unlock(&wait);
      timeout.tv_sec += (60 * prof->interval);
      time(&cur_t);
    }
    break;
  }
fail:
  pthread_cleanup_pop(1);
  pthread_cleanup_pop(1);
  pthread_cleanup_pop(prof->fc);
  pthread_exit(NULL);
}

请记住,您将 values 压入清理堆栈。而当你push这些值的时候,它们是空指针,也就是被push的值。

一种解决方案是使用您自己的“免费”函数,并将指针推送到变量。比如

void free_indirect(void *indirect_ptr)
{
    free(*((void **) indirect_ptr));
}

// ...

pthread_cleanup_push(free_indirect, &dat);