malloc,函数中如何自由返回值

时间:2012-10-16 18:31:46

标签: c memory-leaks malloc return free

我的应用程序在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;

请看一下这三个函数(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. 与新的相同的故事:

             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;
        }
    
  4. 有关更多功能,您可以看到module-datastruct-llist.c

    非常感谢,如果有专家告诉我,我怎么能修复内存泄漏(如果你觉得,cs_malloc应该被重写,或者需要添加新功能,请写下你的意思源代码。

3 个答案:

答案 0 :(得分:0)

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

现在,您可以调用ll_append_nolock,忽略malloced返回。即。

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(如上所述指向以“new”名称分配的存储,即:相同的内存,不同的名称)时,你释放它。

HTH。

答案 1 :(得分:0)

在您的函数cs_malloc中,第一个参数为result,但您从未在函数cs_malloc中为其指定。

稍后你会像这样使用cs_malloc

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

这是行不通的,因为“new”未被初始化

您应该在cs_malloc中分配结果,或者仅在cs_malloc中返回该块,如果您未能分配,只需返回NULL

e.g。

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;
  }

答案 2 :(得分: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;