yunhuizhu / memcached

Automatically exported from code.google.com/p/memcached
0 stars 0 forks source link

Memory leak bug in VERSION 1.4.13 -----the code does not release the memory of Cache object self in "cache_destroy" function #262

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
my mail address:shyandsy@google.com

Firstly,let us to check the function named cache_create() and cache_destroy() 
in cache.c: 

cache_t* cache_create(const char *name, size_t bufsize, size_t align,
                      cache_constructor_t* constructor,
                      cache_destructor_t* destructor) {
    //the memory of cache object
    cache_t* ret = calloc(1, sizeof(cache_t)); 

    char* nm = strdup(name);
    void** ptr = calloc(initial_pool_size, sizeof(void*));
    if (ret == NULL || nm == NULL || ptr == NULL ||
        pthread_mutex_init(&ret->mutex, NULL) == -1) {
        free(ret);
        free(nm);   //free函数可以释放无效指针???
        free(ptr);
        return NULL;
    }

    ret->name = nm;
    ret->ptr = ptr;
    ret->freetotal = initial_pool_size;
    ret->constructor = constructor; //构造函数?会自动调用么??
    ret->destructor = destructor;   //析构函数?会自动调用么??

#ifndef NDEBUG
    ret->bufsize = bufsize + 2 * sizeof(redzone_pattern);
#else
    ret->bufsize = bufsize;
#endif

    return ret;
}

void cache_destroy(cache_t *cache) {
    //release everyone memory block in the ptr
    while (cache->freecurr > 0) {
        void *ptr = cache->ptr[--cache->freecurr];
        if (cache->destructor) {
            cache->destructor(get_object(ptr), NULL);
        }
        free(ptr);
    }
    //release name of cache object
    free(cache->name);
    //release the ptr self
    free(cache->ptr);
    //release the mutex
    pthread_mutex_destroy(&cache->mutex);

    //why you do not release the 
}
 why you do not release the "cache_t *cache"

Secondly,look at the test function in "testapp.c":
static enum test_return cache_constructor_test(void)
{
    cache_t *cache = cache_create("test", sizeof(uint64_t), sizeof(uint64_t),
                                  cache_constructor, NULL);
    assert(cache != NULL);
    uint64_t *ptr = cache_alloc(cache);
    uint64_t pattern = *ptr;
    cache_free(cache, ptr);
    cache_destroy(cache); 
    return (pattern == constructor_pattern) ? TEST_PASS : TEST_FAIL;
}

cache_destroy(cache);  it does not release the cache object self

According to the logical, this is a memory leak bug!!!!!!!!

Original issue reported on code.google.com by shyan...@gmail.com on 23 Mar 2012 at 11:48

GoogleCodeExporter commented 9 years ago
If you grep the sources, you'll see that nothing within memcached actually 
calls cache_destroy.

It *would* leak memory and should probably be fixed.

However there is no memory leak in memcached, as cache collections are created 
and never freed.

Original comment by dorma...@rydia.net on 24 Mar 2012 at 12:08

GoogleCodeExporter commented 9 years ago
wasn't actually a memory leak. fixed anyway.

Original comment by dorma...@rydia.net on 30 Jul 2012 at 9:21

GoogleCodeExporter commented 9 years ago
Thanks for answer.
You are right.

Original comment by shyan...@gmail.com on 30 Jul 2012 at 10:45