I am doing a project of Data Structures in c language in which I have been using some functions like insertion in a tree, deletion from a tree, finding a particular value in a tree. I have to calculate memory using of every individual function like memory usage in insertion function, deletion function e.t.c. Kindly guide me if there is any library or built-in function to calculate memory usage. I have found some content like to find memory usage of whole program but I am concerned with memory usage of a particular function.
Your question is vague, but I will try to answer it like I understand it.
Allocated memory for a tree with lets say 20 Nodes will consume 20xNode size so lets say our Node looks like this:
typedef struct node
{
int val;
struct node * next;
} node_t;
Let's assume you have a 64 bit system, then an integer will take 4 bytes and a pointer would take another 8 bytes. Together Node size will be 12 bytes of allocated memory ready to use.
For our example a tree with 20 nodes will consume 240 bytes of memory.
When you add Nodes to the tree you are basically increasing the memory stored and hence expanding the memory usage.
If you need to keep check of how much memory is used by each function you should calculate each function usage separately(remember that each function stores the variables locally and not globaby) and add the overall allocated or freed memory in the process.
Let's say a function that adds a node looks like this :
void addNode(node_t *leaf, int a)
{
node *new=malloc(sizeof(node));
new->val=a;
new->next=NULL;
*leaf->next=new;
}
this function will add 12 bytes to your overall memory usage.
you can add a counter in your main function to keep track of the memory stored and at the end of an addition add sizeof(node) to the counter via pointers or subtracts from it.
If i understand your question you don't need to keep track of local memory because its not important after the functions end. You just need to keep track of memory added or subtracted after initial allocation for the tree you receive.
To my knowledge there are no function that can do it for you so you will have to add it yourself.
My suggestion to you is to break your program to many little function and at the end of each keep track of what it has done to the overall memory stored.
you can also keep track of local variables but they are deleted at each transition between function (if they are not allocated pointers).
Related
I am implementing a linked list in C and I am running into the issue where C does not implement any specific scheme for memory management other than just giving you the ability to allocate and free memory by passing a pointer. There is no concept of whether the value might be needed later on in the program.
The typical implementation I find online for a linked list basically deallocs the deleted node but does not dealloc the node's value.
Whose responsibility should it be to release the memory taken up by the value when deleted from the list ? The linked list's or the normal flow of the program ?
example:
// allocate 10 bytes
char *text = malloc(sizeof(char) * 10);
// create the linked list
LinkedList *list = list_create();
// add the text pointer to the linked list
list_append(list, text);
// remove the pointer from the linked list
list_remove_last(list);
In this case text would end up not getting deallocated as list_remove_last just frees the memory that the new node takes up. What would be the proper way to release the memory taken up by text ?
that is a very common way of container implementation in C.
basically you dynamically allocate the contents of the list and pass the pointer to the container, now the container is responsible for freeing it.
You can also pass in a function pointer to list_create() so it knows how to do list_remove_last() properly, this is especially useful for using a generic container that does not know what type of elements it will contain (it will just hold void * pointers).
think of the case where the data itself is a struct that contains other pointers. in this case list_remove() can not do a simple free() on its data field, instead it should use the function pointer that was passed in to free the data.
your approach has a small problem:
if you have list* as the return type of list_create(), then you will have to do a free(list) in your main function. alternatively, you can have list_create() return a list, as opposed to a list*, this is a logical choice because a list has its bulk of information dynamically allocated and accessible through a pointer anyway.
in the second case you would need a function list_destroy(list) that would destroy any element your list holds.
C does not implement any specific scheme for memory management other than just giving you the ability to allocate and free memory by passing a pointer
Yes, C lacks any kind of automatic memory management, so you have to be careful to deallocate any memory blocks that you instantiate.
Whose responsibility should it be to release the memory taken up by the value when deleted from the list? The linked list's or the normal flow of the program?
It's your responsibility. You can do it however you like. You can write a general purpose linked list where the caller has to be responsible for allocating and deallocating space for each value in the list because the list management functions don't know how much space each value might require, or whether the values might be needed beyond the lifetime of the node. Or, you can write a list implementation that manages every aspect of the node, including space for the value stored in the node. In some cases, a list node includes the value in the node definition, like:
struct Node {
struct Node *next;
int value;
};
and other times the node has a pointer to some other block that has the actual value:
struct Node {
struct Node *next;
void *value;
};
Another approach is to define a structure with just the part needed for the list operation (i.e. the next pointer), and then piggyback data onto that structure:
struct Node {
struct Node *next;
};
struct MyNode {
struct Node node;
int price;
int quantity;
};
So, there are lots of ways to do it, and none of them are wrong. You should choose the style that makes sense for your needs. Do you have big, complex values that you don't want to duplicate, that you want to store in a linked list, but which you want to continue to use even after they're removed from the list? Go with the first style above. Do you want to manage everything related to the linked list in one place? Then go with the second style.
The point is: C dictates a lot less than other languages do, and while that means that you have to think harder about program correctness, you also get the freedom to do things very directly and in a style of your choosing. Embrace that.
My guide line is: the one who allocates memory is also responsible for de-allocating it.
If you implement a linked list that allocates the memory for the values, the implementation should also take care of freeing this memory when the entries are removed from the list. For strings this could be done by copying the strings to a newly allocated buffer of adequate size.
If your implementation of a linked list only stores plain values (e.g. pointers) without allocating extra memory for the values, it should also avoid freeing memory it did not allocate, because it doesn't know what the allocator planned for this memory in the future.
The proper way would be to have list_remove_node() a function that would free not only the list (node) itself, but also the value that was allocated for that specific node. Also, you shouldn't need to search for a specific node according to your text as you should be able to just call free(node->text) (which can be done even in the current list_remove_last() function)
The main C logic is that you are supposed to free() anything that you allocated yourself. Certain libraries will allocate memory for their own work, which most often you are supposed to clean up as well (as you were the one who asked for it).
In a program I'm writing, I am implementing binary tree and linked list structures; because I don't know how many nodes I will need, I am putting them on the heap and having the program use realloc() if they need more room.
The problem is that such structures include pointers to other locations in the same structure, and because the realloc() moves the structure, I need to redo all those pointers (unless I change them to offsets, but that increases the complexity of the code and the cost of using the structure, which is far more common than the reallocations).
Now, this might not be a problem; I could just take the old pointer, subtract it from the new pointer, and add the result to each of the pointers I need to change. However, this only works if it is possible to subtract two pointers and get the difference in their addresses (and then add that difference to another pointer to get the pointer that many bytes ahead); because I'm working on the heap, I can't guarantee that the difference of addresses will be divisible by the size of the entries, so normal pointer subtraction (which gives the number of objects in between) will introduce errors. So how do I make it give me the difference in bytes, and work even when they are in two different sections of the heap?
To get the difference between two pointers in bytes, cast them to char *:
(char *) ptrA - (char *) ptrB;
However, if you'd like to implement a binary tree or linked list with all nodes sharing the same block of memory, consider using an array of structs instead, with the pointers being replaced by array indices. The primary advantage of using pointers for a linked list or tree, rather than an array of structs, is that you can add or remove nodes individually without reallocating memory or moving other nodes around, but by making the nodes share the same array, you're negating this advantage.
The best way would indeed be to malloc() a new chunk for every node you have. But this might have some overhead for the internal management of the memory, so if you have lots of them, it might be useful to indeed allocate space fore more nodes at once.
If you need to realloc then, you should go another way:
1. Calculate the offset within your memory block: `ofs = ptrX - start`
2. Add this offset to the new address returned by `realloc()`.
This way, you always stay inside the area you allocated and don't have strange heap pointer differences with nearly no meaning.
In fact ,you can use malloc or calloc to get memory for each node.
So you only need to remeber the address of tree's root node.
In this way, you never need realloc memeory for the whole tree . The address of each node also never change . :)
If someone is talking about solving a problem with the C programming language, and they say that dynamically created structures is the way to go, what are they likely to be referring to? Is there another name for this perhaps?
The assignment requires that you use dynamic memory allocation for your data structures. Your program may not use statically allocated memory, that is, for example int array[65536];. Instead all these needs to be allocated on demand using the malloc/calloc/realloc (and supposedly be freed using the free).
C allows you to allocate new memory while a program is running according to your needs (that's why is referred as "dynamical allocation").
For example: you have a very basic structure, a linked list, but you don't know how many nodes are required during the execution of your program. So in your code you declare that every time you need to store a new node in the list, the program must take this x amount of memory and allocate a new node (that will be attached to the existing list)
typedef struct {
int datum;
Node *next;
} Node;
then later on you can cay:
Node *new_node = (Node *)malloc(sizeof(Node);
In the same fashion you can free memory at run time:
free(new_node);
If your question is How to create structure dynamically?
Without knowing what you want to ask, I am just giving an answer, assuming you are asking about this only.
A dynamic data structure is a data structure that changes in size as a program needs it to by allocating and de-allocating memory from the heap -- a term used to describe unused memory available to the central processing unit(CPU) at any given time. A dynamic data structure lets a programmer control precisely how much memory is consumed by his or her program. When a dynamic data structure created in the C programming language allocates blocks of memory from the heap, it uses pointers to link those blocks together into a data structure of some kind. The data structure will return a block of memory to the heap when it doesn't need it any longer. This system of recycling memory blocks makes a program's use of memory very efficient.
I have been told to design a linked list module where the linked list functions will all be in one header file but the memory allocation(malloc) will not happen those modules.
The memory allocation should ONLY happen in the main function. I am unable to figure it out. Do help me.
that has been implemented already: look at <sys/queue.h> that's a header only linked list.
In main you should allocate a sufficiently large amount of memory (A memory pool), in one go. Now in your module you need to manage (allocate and free) memory chunks from this pool, and not bother with malloc.
If you don't know about memory pool, read this - http://en.wikipedia.org/wiki/Memory_pool.
However there is problem of fragmentation, which you need to tackle. In the steps below I use a bit array, to mark the free and allocated nodes.
Example-
In main you allocate 50*sizeof(node) (50 depends on application)
Now, you pass the pointer of allocated pool to your function.
Keep a counter, to count number of allocated nodes, initialize it to 0
Also keep a bit array, of size 50, initialized to 0 (all free)
When allocating, check for overflow, iterate over the bit-array, to find first free node. If j th bit is 0, pass on the address of new node as Base + j(*sizeof node), and increment the counter. Set the j th bit to 1.
When deallocating, simply decrement the counter, and set the corresponding bit to 0.
HTH
You can do this as an array of structures and link it by array index. That array can then be allocated in the main function. Note that you have to keep track of the number of entries you have in your list, as the list will be limited to the number of entries you allocate.
I'm writing a malloc function for a college assignment. Here's a basic layout of my idea:
1)Define a node struct with pointers to previous node, next node, as well as a char for size and vacancy. Each region in the heap will contain a hidden node with this information.
2)Malloc function. Starting with first node loop through each node checking for vacancy. If a node is vacant and is large enough return a ptr to the beginning of the region not including the node. If no space is available use sbrk to allocate requested space PLUS space for a node.
3)Free function. Go to pointer passed as parameter-sizeof(struct node) and set the vacancy to vacant. Then starting with the beginning of the list, traverse the list merging adjacent free spaces.
How does this approach sound? My main concern is with actually starting the linked list. For instance, should I create a node with sbrk before I start to do any allocations and store a ptr to it as a global variable? If so how do I initialize a first node before I allow the malloc function to be called by a driver program?
Thanks in advance. I'm not asking for someone to write my code, only to provide some insight and suggestions regarding my ideas.
I would avoid keeping all the bookkeeping information on nodes while they're allocated. I'd have the bare minimum of information (usually just the block size) at the beginning of the block, but nothing more.
I'd track free blocks and allocated blocks separately, so when you're searching for a free block, you don't waste time on blocks that are already in use.
I'd separate the free list into two pieces, and coalesce blocks lazily. In other words, have one free list you're allocating from, and a second that's just a holding area. When the user calls free, just link the block into the holding area, nothing more. When the list you're using for allocations starts to run low, sort the blocks in the holding area by address, then merge with the allocation free list. Then walk the list and merge adjacent blocks.
When you do need to call sbrk (or whatever) to allocate more space from the system, do not just allocate enough space to satisfy the current allocation request. Instead, allocate a fairly large block (e.g., a megabyte) and then split that to get satisfy the request, and add the rest as block to the free list. If you're running low enough on memory that you have to go to sbrk once, chances are the next few calls will do the same, so you might as well be greedy, and grab enough memory immediately to stand a decent chance of satisfying more requests as well.
The basic idea of the third is to avoid doing coalescing as long as possible to increase the chances of finding adjacent blocks, so when you do coalesce you'll probably do some real good, and avoid wasting time trying to coalesce when there are only a few adjacent blocks free.