简体   繁体   中英

malloc , how free return value in a function

My app is use in stlinux (sh4) and unfortunately valgrind does not support sh4 cpu. since I saw memory leak with my app, I had used mtrace, and it confirmed that some memory is not free. The problem is, variable of malloc used in the return, therefore I do not have any idea, how could I free it (since if it would be free, then returning in the functions is meaningless)?

I had written cs_malloc (put bellow code from oscam-simple.c in above link), mtrace log says, that in line:

*tmp = malloc (size);

memory is not free

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

And then for malloc, I call it, like this:

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

Please take a look at these 3 functions (which malloc is not free , and as other users said, valgrind claim that these codes cause memory leaks module-datastruct-llist.c

The memory leaks cause by 3 different parts:

  1. in below codes "new" would never free , but since it use in return of that function, I don't have idea, how could I free it:

     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. also "l" use in below function, again since it use in return function, I have no idea how to free it. :

      LLIST *ll_create() { LLIST *l = cs_malloc(&l, sizeof(LLIST), 0); pthread_mutex_init(&l->lock, NULL); return l; } 
  3. same story with 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; } 

For more functions you could see module-datastruct-llist.c

Would highly appreciate, if any expert tell me, how could I fix that memory leak (if you feel, cs_malloc should be rewritten, or need to add new function, please write the source code you are meaning.

The most common implementations of malloc use heap memory, which is global, so it's very common to have storage allocated in one place passed around between a number of functions before it is finally freed.

Now, there are for instance calls to ll_append_nolock where you ignore the malloced return. Ie

ll_append_nolock(it->l, obj);

so to avoid a leak you need to do what you do in other places, ie let the calling function receive the allocated memory into a pointer:

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

And when you're through with n (which as noted above points to the storage allocted under the name "new", that is: same memory, different names), you free it.

HTH.

In your function cs_malloc the first parameter is result however you never assign to it in the function cs_malloc .

Later you use cs_malloc like this

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

which will not work since since "new" is left uninitialized

you should either assign to result in your cs_malloc or just return the block in cs_malloc , if you fail to allocate just return NULL instead.

eg

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

and

  if (new = cs_malloc(sizeof(LL_NODE),-1))
  {
    new->obj = obj;
  }
  else
  {
    return NULL;
  }

@Anders Thanks for reply , i would take consideration your note ,an would change it as u described to see memory leaks how it's goes...

How , this line should be change to the new cs_malloc function u had written: 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;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM