user3858887
user3858887

Reputation: 19

Learning C - Why does this method not free memory?

I am using online tutorials to learn C so I can then learn obj-C for a potential job (http://www.learn-c.org/en/Linked_lists)

I am on a lesson where you have to remove the FIRST node from a linked list by value, and I seem to do that with success. Then I make it where it removes ALL nodes with that value, which also seems to work.

typedef struct node {
    int val;
    struct node * next;
    int large[2500];
} node_t;


int remove_by_value(node_t ** head, int val) {

if (*head == NULL){
    return -1;
}
node_t *current = *head;
node_t *previous = NULL;

do{
    if(current->val == val){
        node_t *toDelete = current;
        if(previous != NULL){ //not 1st on the list
            previous->next = current->next;
            current = previous ->next;

        }
        else{ //node to remove is 1st on the list
            *head = (*head)->next; //
            current = *head;       //current = the new head
        }
        free(toDelete);
    }
    else{
        previous = current;
        current = current->next;
    }

}while(current != NULL);
return -1;
}


int main(){
node_t *test_list = malloc(sizeof(node_t));
node_t *current = test_list;
current->val = 37;
for(int i=1; i < 300000; i++){
    current->next= malloc(sizeof(node_t));
    current = current->next;
    current->val = rand()%3;

}

print_list(test_list);
remove_by_value(&test_list, 2);
print_list(test_list);
}

//UPDATE: It seems there is some freeing going on, but I do not understand the memory usage.

sizeof(node_t) ~ 10kB 300,000 node_t = 3 GB //I would expect the program to be using 3GB at this point

However, after creating the 300,000 node_t's in the program, mem usage (within Xcode's profiler) is only showing 1.16GB (is this some optimization, should be 3GB??) I call to remove by value's (the list contains values only from 0 through 3)

{before list created}              // mem usage  288KB
{link list created}                // mem usage 1.16GB
remove_by_value(&test_list, 2);    // mem usage 1.39GB
remove_by_value(&test_list, 3);    // ""        1.17GB
remove_by_value(&test_list, 1);    // ""         759MB  (seems correct)
remove_by_value(&test_list, 0);    // ""          20MB  (why this big still?)

I reran the program and changed the node_t to be 100KB a piece, which means the list should be 30GB. Memory spikes to over 2GB, but slowly goes down to about 500MB. Does anyone know why this is?

Upvotes: 2

Views: 130

Answers (1)

Greg Hewgill
Greg Hewgill

Reputation: 994897

Watching the "memory usage" in some external application does not give you the numbers you are looking for. What you are actually seeing is the amount of memory that your program has requested from the operating system. The operating system does not know how your program is actually using that memory.

In your case, the C runtime library is using the memory itself and keeping track of what is freed and allocated itself. It doesn't need to inform the operating system that this bit is allocated, and that bit was allocated before but is now freed, and that bit over there was requested earlier but has not been used yet.

The effect you will see is that as your program runs, the amount of memory requested from the point of view of the operating system may not go down. This is normal.

Upvotes: 3

Related Questions