All of lore.kernel.org
 help / color / mirror / Atom feed
* problems with free()
       [not found] <c93f91ee0904280218o2f844cd0u2262db407ca8f468@mail.gmail.com>
@ 2009-04-28  9:20 ` leo mueller
       [not found]   ` <6eee1c40904280341n4e332026i7d9800fd4f8059b4@mail.gmail.com>
  2009-04-28 11:22   ` Bert Wesarg
  0 siblings, 2 replies; 5+ messages in thread
From: leo mueller @ 2009-04-28  9:20 UTC (permalink / raw)
  To: linux-c-programming

[-- Attachment #1: Type: text/plain, Size: 344 bytes --]

hi all,

i got a little problem with free() ... i am allocating mem for a
special struct and putting it afterwards
into a linked list. allocating works fine, but freeing not. i'm
tracking the program with htop. after
allocating, the percentage of mem usage stays constant ...

the test-file is attached.

any help is appreciated. big thanks :)

[-- Attachment #2: test.c --]
[-- Type: text/x-csrc, Size: 3551 bytes --]

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

typedef unsigned long long nodeinf;
typedef unsigned long long hashinf;

struct node {
    hashinf hash;
    nodeinf info;
    struct node *parent;
    struct levelcache *childs;
};

struct levelcache {
    unsigned int size;
    unsigned int last;
    struct node **list;
};

struct cache {
    struct levelcache *root;
    struct node *last_node;
};

struct stackframe {
    struct levelcache *lc;
    struct stackframe *next;
};

void release();
inline void push_to_stack(struct levelcache *);
void free_stack();
inline void add_to_list(struct node *);
struct stackframe *sfalloc();
struct node *nalloc();
struct levelcache *lcalloc(int);
void lcrealloc(struct levelcache *, int);

struct stackframe *garbage;

/*
 * Pushes element to garbage stack
 */
inline void push_to_stack(struct levelcache *l)
{
    struct stackframe *sf;

    sf = sfalloc();
    sf->lc = l;
    sf->next = garbage;
    
    garbage = sf;
}
	
/*
 * Frees garbage stack
 */
void free_stack()
{
    int i;
    int j = 0;
    void *rc;
    struct stackframe *sf;
    
    while(garbage != NULL){
        sf = garbage->next;
        
        garbage->next = NULL;
        
        for(i = 0; i < garbage->lc->size; ++i){
            if(garbage->lc->list[i] != NULL){
                j++;
                printf("free adr: 0x%x\n", (unsigned int) garbage->lc->list[i]);
                rc = realloc(garbage->lc->list[i], 0);
                printf("free adr: 0x%x\n", (unsigned int) rc);
            }
        }
        free(garbage->lc->list);
        free(garbage->lc);
        free(garbage);
        
        garbage = sf;
    }
    
    printf("%d elem freed.\n", j);
}

/*
 * Allocation of a stackframe
 */
struct stackframe *sfalloc()
{
    struct stackframe *sf = (struct stackframe *) malloc(sizeof(struct stackframe));
    
    if(!sf){
        fprintf(stderr, "error: malloc stackframe\n");
        release();
        exit(1);
    }

    memset(sf, 0, sizeof(struct stackframe));
    return sf;
}

/*
 * Allocation of a single node
 */
struct node *nalloc()
{
    struct node *n = (struct node *) malloc(sizeof(struct node));
    
    if(!n){
        fprintf(stderr, "error: malloc node\n");
        release();
        exit(1);
    }

    memset(n, 0, sizeof(struct node));
    return n;
}

/*
 * Allocation of a levelcache element
 */
struct levelcache *lcalloc(int n)
{
    int i;
    struct levelcache *l;

    if(!n)
        return NULL;

    l = (struct levelcache *) malloc(sizeof(struct levelcache));

    if(!l){
        fprintf(stderr, "error: malloc levelcache\n");
        release();
        exit(1);
    }
    
    l->list = (struct node **) malloc(sizeof(struct node *) * n);

    if(!l->list){
        fprintf(stderr, "error: malloc node list\n");
        release();
        exit(1);
    }
    
    l->size = n;
    l->last = 0;

    for(i = 0; i < l->size; ++i)
        l->list[i] = NULL;

    return l;
}

/*
 * Drops our whole cache
 */
void release()
{
    free_stack();
}

/*
 * Main routine
 */
int main(int argc, char **argv)
{
    int i, j;
    struct levelcache *l;

    garbage = NULL;

    for(i = 0; i < 200; ++i){
        l = lcalloc(2000);
        
        for(j = 0; j < l->size; ++j){
            l->list[j] = nalloc();
            l->list[j]->hash = j;
            l->list[j]->info = j;
            printf("alloc adr: 0x%x\n", (unsigned int) l->list[j]);
        }
        
        push_to_stack(l);
    }

    release();
    
    sleep(5);
    return 0;
}

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: problems with free()
       [not found]   ` <6eee1c40904280341n4e332026i7d9800fd4f8059b4@mail.gmail.com>
@ 2009-04-28 11:10     ` leo mueller
  2009-04-28 14:48       ` Trevor Woollacott [ MTN - Innovation Centre ]
  0 siblings, 1 reply; 5+ messages in thread
From: leo mueller @ 2009-04-28 11:10 UTC (permalink / raw)
  To: Vadiraj; +Cc: linux-c-programming

hi vadiraj,

thanks for your answer! first i thought about that, too, but if i do a
simple ...

char *x = (char *) malloc(1024 * 1024 * 100);
memset(x, 0, 1024 * 1024 * 100);
free(x);

... and put some sleeps in between (& before return)... i can see (->
htop) that
the % of mem is decreasing during runtime.... hmm...

2009/4/28 Vadiraj <vadiraj.cs@gmail.com>:
>
> On Tue, Apr 28, 2009 at 2:50 PM, leo mueller <llug.dan@googlemail.com>
> wrote:
>>
>> hi all,
>>
>> i got a little problem with free() ... i am allocating mem for a
>> special struct and putting it afterwards
>> into a linked list. allocating works fine, but freeing not. i'm
>> tracking the program with htop. after
>> allocating, the percentage of mem usage stays constant ...
>>
>> the test-file is attached.
>>
>> any help is appreciated. big thanks :)
>
> free() will put the chunk into the free pool of the process and not free
> away from the
> process. When you do a malloc again it would first try from the free pool,
> if it finds
> the size requested in the free pool it will give you the same.
> Hence you would not see any change.
>
> You can check that by, freeing an address and then requesting the same size.
> You will see that address freed and address allocated will be same in most
> of
> the case.
>
> Hope this helps.
>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: problems with free()
  2009-04-28  9:20 ` problems with free() leo mueller
       [not found]   ` <6eee1c40904280341n4e332026i7d9800fd4f8059b4@mail.gmail.com>
@ 2009-04-28 11:22   ` Bert Wesarg
  2009-04-28 12:52     ` leo mueller
  1 sibling, 1 reply; 5+ messages in thread
From: Bert Wesarg @ 2009-04-28 11:22 UTC (permalink / raw)
  To: leo mueller; +Cc: linux-c-programming

On Tue, Apr 28, 2009 at 11:20, leo mueller <llug.dan@googlemail.com> wrote:
> hi all,
>
> i got a little problem with free() ... i am allocating mem for a
> special struct and putting it afterwards
> into a linked list. allocating works fine, but freeing not. i'm
> tracking the program with htop. after
> allocating, the percentage of mem usage stays constant ...
Can you at least describe what do you expect to happen, and what does
not work with freeing?

bert
>
> the test-file is attached.
>
> any help is appreciated. big thanks :)
>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: problems with free()
  2009-04-28 11:22   ` Bert Wesarg
@ 2009-04-28 12:52     ` leo mueller
  0 siblings, 0 replies; 5+ messages in thread
From: leo mueller @ 2009-04-28 12:52 UTC (permalink / raw)
  To: Bert Wesarg; +Cc: linux-c-programming

yeah, i was just wondering why doing a free() on the last example (the
char* stuff...) decreased the used mem by 'a.out' _immediately_ and on
my first example (source attached in 1st mail) _not_ (nothing happened
after free; only the os cleaned up after exit). i tried that several
times and got the same behaviour as mentioned, so i thought there
might be a bug in my source....

another fact would proof my assumption....

during programming (on that source) i first cleaned up my mem
recursively... which ended up in segfault when allocating more than
(e.g.) 1.5gig over the time, so a stack overflow might occur. instead
of
traversing my built tree recursively, i thought about putting the
lists with nodes (my 'parts' of the tree) into a linked list to solve
this issue. but i'm wondering about the following fact... freeing
recursivly made a visible decrease of my used mem in 'htop' while
freeing with my iterative variant made no decrease at all... so i
thought about a bug in my program... (but cannot find it....)

2009/4/28 Bert Wesarg <bert.wesarg@googlemail.com>:
> On Tue, Apr 28, 2009 at 11:20, leo mueller <llug.dan@googlemail.com> wrote:
>> hi all,
>>
>> i got a little problem with free() ... i am allocating mem for a
>> special struct and putting it afterwards
>> into a linked list. allocating works fine, but freeing not. i'm
>> tracking the program with htop. after
>> allocating, the percentage of mem usage stays constant ...
> Can you at least describe what do you expect to happen, and what does
> not work with freeing?
>
> bert
>>
>> the test-file is attached.
>>
>> any help is appreciated. big thanks :)
>>
>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* RE: problems with free()
  2009-04-28 11:10     ` leo mueller
@ 2009-04-28 14:48       ` Trevor Woollacott [ MTN - Innovation Centre ]
  0 siblings, 0 replies; 5+ messages in thread
From: Trevor Woollacott [ MTN - Innovation Centre ] @ 2009-04-28 14:48 UTC (permalink / raw)
  To: leo mueller, Vadiraj; +Cc: linux-c-programming

>From: linux-c-programming-owner@vger.kernel.org [mailto:linux-c-programming-owner@vger.kernel.org] On Behalf Of leo mueller
>Sent: Tuesday, 28 April 2009 01:10 PM
>To: Vadiraj
>Cc: linux-c-programming@vger.kernel.org
>Subject: Re: problems with free()
>
>hi vadiraj,
>
>thanks for your answer! first i thought about that, too, but if i do a
>simple ...
>
>char *x = (char *) malloc(1024 * 1024 * 100);
>memset(x, 0, 1024 * 1024 * 100);
>free(x);
>
>... and put some sleeps in between (& before return)... i can see (->
>htop) that
>the % of mem is decreasing during runtime.... hmm...
>
>2009/4/28 Vadiraj <vadiraj.cs@gmail.com>:
>>
>> On Tue, Apr 28, 2009 at 2:50 PM, leo mueller <llug.dan@googlemail.com>
>> wrote:
>>>
>>> hi all,
>>>
>>> i got a little problem with free() ... i am allocating mem for a
>>> special struct and putting it afterwards
>>> into a linked list. allocating works fine, but freeing not. i'm
>>> tracking the program with htop. after
>>> allocating, the percentage of mem usage stays constant ...
>>>
>>> the test-file is attached.
>>>
>>> any help is appreciated. big thanks :)
>>
>> free() will put the chunk into the free pool of the process and not free
>> away from the
>> process. When you do a malloc again it would first try from the free pool,
>> if it finds
>> the size requested in the free pool it will give you the same.
>> Hence you would not see any change.
>>
>> You can check that by, freeing an address and then requesting the same size.
>> You will see that address freed and address allocated will be same in most
>> of
>> the case.
>>
>> Hope this helps.
>>

Vadiraj is correct. I'm not going into the details of how malloc() and free() work, but (very) basically, when you use malloc() the heap is searched for a free chunk. If there isn't a large enough chunk available, it will make more space available on the heap using the syscall brk(). When you call free(), the chunk is given back to the heap, making it available for a later stage. Even after free, the heap usually stays that size and the memory isn't returned to the OS immediately (It may depend on the C implementation).
But I think that in order to keep the number of brk() syscalls to a minimum (for optimal performance), it will probably wait until there is one large chunk that can be freed instead of freeing lots of smaller chunks.


NOTE: This e-mail message is subject to the MTN Group disclaimer see http://www.mtn.co.za/SUPPORT/LEGAL/Pages/EmailDisclaimer.aspx

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2009-04-28 14:48 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <c93f91ee0904280218o2f844cd0u2262db407ca8f468@mail.gmail.com>
2009-04-28  9:20 ` problems with free() leo mueller
     [not found]   ` <6eee1c40904280341n4e332026i7d9800fd4f8059b4@mail.gmail.com>
2009-04-28 11:10     ` leo mueller
2009-04-28 14:48       ` Trevor Woollacott [ MTN - Innovation Centre ]
2009-04-28 11:22   ` Bert Wesarg
2009-04-28 12:52     ` leo mueller

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.