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



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

我已经写了cs_malloc(把下面的代码放在上面的链接中),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声称这些代码导致内存泄漏模块datastruct-list.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;
    }
    

有关更多功能,请参阅模块数据结构llist.c

如果有专家告诉我,我该如何修复内存泄漏,我将不胜感激(如果你觉得cs_malloc应该重写,或者需要添加新功能,请写下你想要的源代码。

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

现在,有一些对ll_append_nolock的调用,您可以忽略mallocated返回。即

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。

在函数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;
}

@Anders谢谢回复,我会考虑你的笔记,我会按照你的描述更改它,看看内存泄漏的情况。。。

如何将这一行更改为u编写的新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;

最新更新