Separating the linked list implementation from the malloc function - c

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.

Related

memory usage of a particular function in c program

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).

implement of a queue(fifo)

Iv'e been given a mission to implement a dynamic queue in c language without any loops and any recursion.
the queue should contain the next function: installation, destruct, add, remove and peek.
I thought to make a link structure, that way each link will have a pointer the next link and so on..but the problem is that I don't know how to do the destruct function without any loops, the only solution I can think of is making a loop that will send each one of the links to the remove function(but again, I need to it without any loops). Is their any possibility to do the destruct function without any loops?
p.s the destruct function should free all of the memory that we used for the queue.
If a recursing function doesn't count as a loop for your constrains, you could use recursion to traverse the list and destroy the items.
Another approach is to store items in an array, and maintain a pointer into the array for the head and tail of the queue. Destroying the queue just means freeing the array or resetting the head/tail pointers, and no loops would be required.
There's no real need to make a queue based on a linked list, it would have all the downside of random allocated elements and lack of spatial locality, would be relatively harder to debug, and won't use the main benefit of a linked list (insertion at O(1)) since it's a queue with only one insertion point anyway (or 2 for a double-ended one).
Instead you could use an array, and maintain a head and tail index variables, use cyclic incrementation when they wrap around at the end, and reallocate when required. If the queue holds basic data types this would also allow you to deallocate the entire queue in one go, just free the array (although for elements you had to manually allocate, I can't see any way to avoid iterated removal, unless you move to c++).
I am assuming that the item to be inserted in memory is of constant size. If needed, it could be a pointer to a block of memory. In that case, you can use a circular buffer with a head and tail pointer. When either pointer "gets to the end of the block" it should wrap - i.e. you increment / decrement modulo queue size.
Initialization:
Create a memory space of finite size (max size of the buffer)
Add:
Update memory location at the current tail (if add to end)
or head (if add to beginning), and update the tail/head pointer.
Remove:
Read the data at the head/tail, and update the pointer
Peek:
Read the data at the head/tail, and don't move the pointer
Destruct:
Free the memory block
No loops, no recursion. It uses the fact that a FIFO buffer only allows changes at the beginning / end of the queue- it is not possible to remove elements "in the middle".
If the head and tail pointers meet, the queue is "full". In that case, the "insert" function should return an error, unless you add a "insert destructively" flag that says "overwrite the oldest element". That seems beyond the scope of your homework, but it is important in real life applications. Sometimes you care about the oldest data - at other times you care about the latest data. But usually, if your queue is filling up, there is a problem with the over all system design (you didn't scale the process that empties the queue to deal with the rate at which it is filling, basically).
Note - if each element in the queue is a pointer to dynamically allocated memory you WILL need to iterate over all elements to free that memory, or you will create a memory leak. But if the queue is of constant size, this is not needed. Given the constraints given, and the lack of specification that queue element size should be variable, I would recommend you write your solution for a fixed size queue element.

How do I add/subtract pointers to different sections of the heap (in C)

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 . :)

Opinions and suggestions regarding my approach to first fit malloc function

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.

Efficient heap-manager for heavy churn, tiny allocs?

I'm looking for ideas for a heap-manager to handle a very specific situation: Lots and lots of very small allocations, ranging from 12 to 64 bytes each. Anything bigger, I will pass on to the regular heap-manager, so only tiny blocks need be catered for. Only 4-byte alignment is needed.
My main concerns are
Overhead. The regular libc heap will typically round up an allocation to a multiple of 16 bytes, then add another 16 byte header - this means over 50% overhead on a 20-byte allocation, which sucks.
Performance
One helpful aspect is that Lua (which is the user of this heap) will tell you the size of the block it's freeing when it calls free() - this may enable certain optimisations.
I'll post my current approach, which works ok, but I'd like to improve on it if at all possible. Any ideas?
It is possible to build a heap manager that is very efficient for objects that are all the same size. You could create one of these heaps for each size of object that you need, or if you don't mind using a bit of space, create one for 16 byte objects, one for 32, and one for 64. The maximum overhead would be 31 bytes for a 33 byte allocation (which would go on the 64 blocksize heap).
To expand on what Greg Hewgill says, one way to do an ultra-efficient fixed-size heap is:
Split a big buffer into nodes. Node size must be at least sizeof(void*).
String them together into a singly-linked list (the "free list"), using the first sizeof(void*) bytes of each free node as a link pointer. Allocated nodes will not need a link pointer, so per-node overhead is 0.
Allocate by removing the head of the list and returning it (2 loads, 1 store).
Free by inserting at the head of the list (1 load, 2 stores).
Obviously step 3 also has to check if the list's empty, and if so do a bunch of work getting a new big buffer (or fail).
Even more efficient, as Greg D and hazzen say, is to allocate by incrementing or decrementing a pointer (1 load, 1 store), and not offer a way to free a single node at all.
Edit: In both cases, free can deal with the complication "anything bigger I pass on the regular heap-manager" by the helpful fact that you get the size back in the call to free. Otherwise you'd be looking at either a flag (overhead probably 4 bytes per node) or else a lookup in some kind of record of the buffer(s) you've used.
The answer may depend on the lifetime patterns for these objects. If the objects are all instantiated as you proceed, and then all removed in one fell swoop, it may make sense to create a very simple heap manager that allocates memory by simply incrementing a pointer. Then, when you're done, blow away the entire heap.
Raymond Chen made an interesting post that may help to inspire you. :)
I like onebyones answer.
You might also consider The buddy system for your sets of fixed size heaps.
If a bunch of memory is allocated, used, and freed before moving on to the next round of allocation, I'd suggest using the simplest allocator possible:
typedef struct _allocator {
void* buffer;
int start;
int max;
} allocator;
void init_allocator(size_t size, allocator* alloc) {
alloc->buffer = malloc(size);
alloc->start = 0;
alloc->max = size;
}
void* allocator_malloc(allocator* alloc, size_t amount) {
if (alloc->max - alloc->start < 0) return NULL;
void* mem = alloc->buffer + alloc->start;
alloc->start += bytes;
return mem;
}
void allocator_free(allocator* alloc) {
alloc->start = 0;
}
I use a mostly O(1) Small Block Memory Manager (SBMM). Basically it works this way:
1) It allocates larger SuperBlocks from the OS and tracks the Start+End Addresses as a range. The size of the SuperBlock is adjustable but 1MB makes a pretty good size.
2) The SuperBlocks are broken into Blocks (also adjustable in size... 4K-64K is good depending on your app). Each of these Blocks handles allocations of a specific size and stores all the items in the Block as a singly linked list. When you allocate a SuperBlock, you make a linked list of Free Blocks.
3) Allocating an Item means A) Checking to see if there is a Block with Free Items handling that size - and if not, allocating a new Block from the SuperBlocks. B) Removing the Item from the Block's Free List.
4) Freeing an Item by address means A) Finding SuperBlock containing address(*) B) Finding Block in SuperBlock (substract SuperBlock start address and divide by Block size) C) Pushing Item back on the Block's Free Item list.
As I stated, this SBMM is very fast as it runs with O(1) performance(*). In the version I have implemented, I use an AtomicSList (similar to SLIST in Windows) so that it is not only O(1) performance but also ThreadSafe and LockFree in the implementation. You could actually implement the algorithm using Win32 SLIST if you wanted to.
Interestingly, the algorithm for allocating Blocks from the SuperBlocks or Items from the Blocks result in nearly identicaly code (they're both O(1) allocations off a Free List).
(*) The SuperBlocks are arranged in a rangemap with O(1) average performance (but a potential O(Lg N) for worstcase where N is the number of SuperBlocks). The width of the rangemap depends on knowing roughly how much memory you're going to need in order to get the O(1) performance. If you overshoot, you'll waste a bit of memory but still get O(1) performance. If you undershoot, you'll approach O(Lg N) performance but the N is for the SuperBlock count -- not the item count. Since the SuperBlock count is very low compared to the Item count (by about 20 binary orders of magnitude in my code), it is not as critical as the rest of the allocator.

Resources