2

我的应用程序在 stlinux (sh4) 中使用,不幸的是 valgrind 不支持 sh4 cpu。因为我看到我的应用程序存在内存泄漏,所以我使用了 mtrace,它确认某些内存不是空闲的。问题是,在返回中使用了 malloc 的变量,因此我不知道如何释放它(因为如果它是免费的,那么在函数中返回是没有意义的)?

我已经编写了 cs_malloc(将来自 oscam-simple.c 的波纹管代码放在上面的链接中),mtrace 日志说,这符合:

*tmp = malloc (size);

内存不是免费的

 /* This function encapsulates malloc. It automatically adds an error message to the log if it failed and calls cs_exit(quiterror) if quiterror > -1. 
       result will be automatically filled with the new memory position or NULL on failure. */
    void *cs_malloc(void *result, size_t size, int32_t quiterror){
        void **tmp = result;
        *tmp = malloc (size);
        if(*tmp == NULL){
            cs_log("Couldn't allocate memory (errno=%d %s)!", errno, strerror(errno));
            if(quiterror > -1) cs_exit(quiterror);
        } else {
            memset(*tmp, 0, size);  
        }
        return *tmp;
    }

然后对于 malloc,我称之为:

  // create the AES key entry for the linked list
    if(!cs_malloc(&new_entry, sizeof(AES_ENTRY), -1)) return;

请看一下这 3 个函数(其中 malloc 不是免费的,正如其他用户所说,valgrind 声称这些代码会导致内存泄漏module-datastruct-llist.c

内存泄漏由 3 个不同的部分引起:

  1. 在下面的代码中,“new”永远不会释放,但由于它使用该函数作为回报,我不知道如何释放它:

    LL_NODE* ll_append_nolock(LLIST *l, void *obj)
    {
    if (l && obj) {
        LL_NODE *new;
        if(!cs_malloc(&new,sizeof(LL_NODE), -1)) return NULL;
        new->obj = obj;
    
        if (l->last)
            l->last->nxt = new;
        else
            l->initial = new;
        l->last = new;    
    
        l->count++;
        return new;
        }  
        }
    
  2. 在下面的函数中也使用“l”,再次因为它在返回函数中使用,我不知道如何释放它。:

      LLIST *ll_create()
      {
       LLIST *l = cs_malloc(&l, sizeof(LLIST), 0);
       pthread_mutex_init(&l->lock, NULL);
       return l;
       }
    
  3. 与 new 相同的故事:

             LL_NODE *ll_prepend(LLIST *l, void *obj)
            {             
            if (l && obj) {
    
            LL_NODE *new;
            if(!cs_malloc(&new,sizeof(LL_NODE), -1)) return NULL;
    
            new->obj = obj;
            ll_lock(l);
            new->nxt = l->initial;
    
            l->initial = new;
            if (!l->last)
                l->last = l->initial;
            l->count++;
            ll_unlock(l);
    
            return new;
        }
           return NULL;
        }
    

有关更多功能,您可以查看module-datastruct-llist.c

非常感谢,如果有专家告诉我,我该如何解决内存泄漏(如果你觉得应该重写 cs_malloc ,或者需要添加新功能,请编写你想要的源代码。

4

3 回答 3

0

malloc 最常见的实现使用堆内存,它是全局的,因此在最终释放之前在多个函数之间传递在一个地方分配的存储是很常见的。

现在,例如对 ll_append_nolock 的调用,您忽略了 malloced 返回。IE

ll_append_nolock(it->l, obj);

所以为了避免泄漏,你需要做你在其他地方所做的事情,即让调用函数将分配的内存接收到一个指针中:

LL_NODE *n = ll_append_nolock(l, obj);
/* do stuff with "n", which points to memory allocated under the name of "new" */
free(n);

当你用完 n 时(如上所述,它指向以“新”名称分配的存储空间,即:相同的内存,不同的名称),你释放它。

HTH。

于 2012-10-16T19:24:12.517 回答
0

@Anders感谢您的回复,我会考虑您的笔记,并会按照您的描述进行更改以查看内存泄漏的情况...

怎么样,这行应该改成你写的新的cs_malloc函数: 1。

    LLIST *l = cs_malloc(&l, sizeof(LLIST), 0);
    pthread_mutex_init(&l->lock, NULL);
    return l;

2.

if(!cs_malloc(&para,sizeof(struct read_thread_param), -1)) return FALSE;
            para->id=i;
于 2012-10-16T22:23:00.787 回答
0

但是,在您的函数cs_malloc中,第一个参数是result您永远不会在函数中分配给它的cs_malloc

以后你cs_malloc像这样使用

if(!cs_malloc(&new,sizeof(LL_NODE), -1)) return NULL;
    new->obj = obj;

这将不起作用,因为“新”未初始化

如果分配失败,您应该分配给您cs_malloc的块或只返回块cs_malloc,如果您未能分配,则NULL改为返回。

例如

void *cs_malloc(size_t size, int32_t quiterror)
{
  void* tmp = calloc(1,size);
  if(tmp == NULL)
  {
    cs_log("Couldn't allocate memory (errno=%d %s)!", errno, strerror(errno));
    if(quiterror > -1) cs_exit(quiterror);
  } 
  return tmp;
}

  if (new = cs_malloc(sizeof(LL_NODE),-1))
  {
    new->obj = obj;
  }
  else
  {
    return NULL;
  }
于 2012-10-16T20:49:23.340 回答