I am working on a trace tool for multithread applications, more especially about memory allocation.
I would like a per thread memory allocation. I know that when a thread do a malloc, the memory used is the global heap. I would like to trace which thread allocated how much memory.
I did a wrapper upon malloc, incrementing values each time there is a malloc as:
void *mymalloc(size_t size) {
mem_used[thread_id] += size;
return malloc(size);
}
It works well. The problem is with free method, which does not return how much memory is released.
Don't take into account my solution, it is just to show what I tried.
EDIT:
As mentionned above, keeping my own table is a too heavy method.
how about changing mymalloc to do:
int* mymem = malloc(size + sizeof(int)*2);
mymem[0] = thread_id;
mymem[1] = size;
mem_used[thread_id] += size;
return &mymem[2].
Then, in myfree(void* mem), you:
void myfree(void* mem)
{
int* imem = (int*)(mem - sizeof(int)*2);
int thread_id = imem[0];
int size = imem[1];
mem_used[thread_id] -= size;
free(imem);
}
this can be optimized, but I hope you get the idea...
The only think I can think of (although you probably considered this) is keeping an allocation table whit these columns:
ThreadID (of course)
Pointer
Allocated size
Then, you will have to use your own malloc and free functions to do the actual mallocing and freeing, but also keeping the allocation table updated.
Is this for debugging purposes? Because otherwise, the overhead of maintaining this table can be significant.
It's a little more complicated. Off the top-of-my-head:
Create a map with the pointer value and memory size allocated for that pointer.
In your my_malloc, update the map with the size argument.
Write your own wrapper for free subtracting the size (which you retrieve by looking up the pointer value) for that thread.
Related
I have been reading that malloc is used for dynamic memory allocation. But if the following code works...
int main(void) {
int i, n;
printf("Enter the number of integers: ");
scanf("%d", &n);
// Dynamic allocation of memory?
int int_arr[n];
// Testing
for (int i = 0; i < n; i++) {
int_arr[i] = i * 10;
}
for (int i = 0; i < n; i++) {
printf("%d ", int_arr[i]);
}
printf("\n");
}
... what is the point of malloc? Isn't the code above just a simpler-to-read way to allocate memory dynamically?
I read on another Stack Overflow answer that if some sort of flag is set to "pedantic", then the code above would produce a compile error. But that doesn't really explain why malloc might be a better solution for dynamic memory allocation.
Look up the concepts for stack and heap; there's a lot of subtleties around the different types of memory. Local variables inside a function live in the stack and only exist within the function.
In your example, int_array only exists while execution of the function it is defined in has not ended, you couldn't pass it around between functions. You couldn't return int_array and expect it to work.
malloc() is used when you want to create a chunk of memory which exists on the heap. malloc returns a pointer to this memory. This pointer can be passed around as a variable (eg returned) from functions and can be used anywhere in your program to access your allocated chunk of memory until you free() it.
Example:
'''C
int main(int argc, char **argv){
int length = 10;
int *built_array = make_array(length); //malloc memory and pass heap pointer
int *array = make_array_wrong(length); //will not work. Array in function was in stack and no longer exists when function has returned.
built_array[3] = 5; //ok
array[3] = 5; //bad
free(built_array)
return 0;
}
int *make_array(int length){
int *my_pointer = malloc( length * sizeof int);
//do some error checking for real implementation
return my_pointer;
}
int *make_array_wrong(int length){
int array[length];
return array;
}
'''
Note:
There are plenty of ways to avoid having to use malloc at all, by pre-allocating sufficient memory in the callers, etc. This is recommended for embedded and safety critical programs where you want to be sure you'll never run out of memory.
Just because something looks prettier does not make it a better choice.
VLAs have a long list of problems, not the least of which they are not a sufficient replacement for heap-allocated memory.
The primary -- and most significant -- reason is that VLAs are not persistent dynamic data. That is, once your function terminates, the data is reclaimed (it exists on the stack, of all places!), meaning any other code still hanging on to it are SOL.
Your example code doesn't run into this problem because you aren't using it outside of the local context. Go ahead and try to use a VLA to build a binary tree, then add a node, then create a new tree and try to print them both.
The next issue is that the stack is not an appropriate place to allocate large amounts of dynamic data -- it is for function frames, which have a limited space to begin with. The global memory pool, OTOH, is specifically designed and optimized for this kind of usage.
It is good to ask questions and try to understand things. Just be careful that you don't believe yourself smarter than the many, many people who took what now is nearly 80 years of experience to design and implement systems that quite literally run the known universe. Such an obvious flaw would have been immediately recognized long, long ago and removed before either of us were born.
VLAs have their place, but it is, alas, small.
Declaring local variables takes the memory from the stack. This has two ramifications.
That memory is destroyed once the function returns.
Stack memory is limited, and is used for all local variables, as well as function return addresses. If you allocate large amounts of memory, you'll run into problems. Only use it for small amounts of memory.
When you have the following in your function code:
int int_arr[n];
It means you allocated space on the function stack, once the function will return this stack will cease to exist.
Image a use case where you need to return a data structure to a caller, for example:
Car* create_car(string model, string make)
{
Car* new_car = malloc(sizeof(*car));
...
return new_car;
}
Now, once the function will finish you will still have your car object, because it was allocated on the heap.
The memory allocated by int int_arr[n] is reserved only until execution of the routine ends (when it returns or is otherwise terminated, as by setjmp). That means you cannot allocate things in one order and free them in another. You cannot allocate a temporary work buffer, use it while computing some data, then allocate another buffer for the results, and free the temporary work buffer. To free the work buffer, you have to return from the function, and then the result buffer will be freed to.
With automatic allocations, you cannot read from a file, allocate records for each of the things read from the file, and then delete some of the records out of order. You simply have no dynamic control over the memory allocated; automatic allocations are forced into a strictly last-in first-out (LIFO) order.
You cannot write subroutines that allocate memory, initialize it and/or do other computations, and return the allocated memory to their callers.
(Some people may also point out that the stack memory commonly used for automatic objects is commonly limited to 1-8 mebibytes while the memory used for dynamic allocation is generally much larger. However, this is an artifact of settings selected for common use and can be changed; it is not inherent to the nature of automatic versus dynamic allocation.)
If the allocated memory is small and used only inside the function, malloc is indeed unnecessary.
If the memory amount is extremely large (usually MB or more), the above example may cause stack overflow.
If the memory is still used after the function returned, you need malloc or global variable (static allocation).
Note that the dynamic allocation through local variables as above may not be supported in some compiler.
I am reading and experimenting pointers from this book,
http://shop.oreilly.com/product/0636920028000.do
In chapter 6 of this book under Avoiding malloc/free Overhead heading
author is suggesting how to avoid malloc/free overhead when doing lots of structure memory allocations/deallocations.
Below is the way he wrote the functions,
#define LIST_SIZE 10
Person *list[LIST_SIZE];
void initializeList()
{
int i=0;
for(i=0; i<LIST_SIZE; i++)
{
list[i] = NULL;
}
}
Person *getPerson()
{
int i=0;
for(i=0; i<LIST_SIZE; i++)
{
if(list[i] != NULL)
{
Person *ptr = list[i];
list[i] = NULL;
return ptr;
}
}
Person *person = (Person*)malloc(sizeof(Person));
return person;
}
void deallocatePerson(Person *person)
{
free(person->firstName);
free(person->lastName);
free(person->title);
}
Person *returnPerson(Person *person)
{
int i=0;
for(i=0; i<LIST_SIZE; i++)
{
if(list[i] == NULL)
{
list[i] = person;
return person;
}
}
deallocatePerson(person);
free(person);
return NULL;
}
What I understood from his code, that he creates a memory pool array, pointing to struct person type and then initialize each array element with NULL.
Next we will get a memory from pool using getPerson function. This function, checks against !=NULL which I think will fail every time. So again it will be same, as doing malloc and memory is not getting assigned from the pool anytime.
Is my understanding correct?
Is this the way to handle overhead ?
What should be the correct way to do it? Any source/link would be appreciated.
Next we will get a memory from pool using getPerson function. This function, checks against !=NULL which I think will fail every time.
The check will fail every time as long as you continue calling getPerson repeatedly. However, if you do a mixture of getPerson and returnPerson, some NULL checks will succeed, because returnPerson puts non-NULL values into the array.
This observation is key to understanding the approach: the array serves as a small temporary storage for struct Person blocks that have been allocated with malloc, but are no longer in use. Rather than calling malloc again, your code grabs an available block from this special list, if there is one available.
In situations when you make thousands of allocations, but never keep more than LIST_SIZE objects active at any given time, the number of malloc calls is limited to LIST_SIZE.
Is this the way to handle overhead?
This is a variation on using lookaside lists, an optimization technique so important that Microsoft created an API for its use in driver code. A simpler approach would use Person *list[LIST_SIZE] as a stack of released blocks, i.e. with the index of the last released block and no loop.
Another approach would be to set up a linked list of such blocks, reusing the memory of the block itself to store the next pointer. This technique may be too complex for an introductory boo, though.
First of all what your writer referring to overhead here? For dynamic memory allocation we call malloc to allocate memory and free to release the memory. Also during this process Operating System need to search for available memory from heap and allocate the same as well. To avoid this overhead, he is just suggesting that at the very beginning when your application load and if you know the frequency of probable dynamic memory allocation to a struct, you can in advance reserved a pool of memory which will reduce allocation and deallocation of memory overhead significantly. That is true to a certain extent, if your server is already running a lots of application and processors are very busy you can go for this kind of approach. But there are drawbacks as well. In this case you already reserved a pool of memory from your heap in advance. If not utilized properly it will leads to poor memory management.
I think the point of the example might be that a Person object holds pointers to additional memory. We can see from the deallocatePerson function that there are 3 pointers to strings inside the struct:
void deallocatePerson(Person *person)
{
free(person->firstName);
free(person->lastName);
free(person->title);
}
It means that to construct a complete Person you need several calls to malloc (1 for the struct itself and 3 for the strings).
So by saving a complete struct, including its strings, one getPerson call replaces four calls to malloc. That makes it likely to save some execution time.
Otherwise, I would not be surprised if malloc/free internally holds a similar array or linked list of recently used memory blocks ready to be recycled. If you have just free'd a memory block of the correct size, a new call to malloc will likely locate that block very fast.
Had Person been a simple struct without pointers to additional storage, the local caching is not that likely to improve performance (but perhaps instead add overhead by doing a linear search).
Which it is the correct way to release the memory in this case; there is some difference between the two methods?
void allocateArray1(int size, int value)
{
int* arr = malloc(size * sizeof(int));
/* ... */
free(arr);
}
int* allocateArray2(int size, int value)
{
int* arr = malloc(size * sizeof(int));
/* ... */
return arr;
}
int main()
{
int* vector = allocateArray2(5,45);
free(vector);
allocateArray1(5,45);
return 0;
}
They are equivalent, because both allocation with malloc and release with free. The allocateArray1 method does it all in one function, which makes it easier to remember to free the memory. But sometimes you need the function to provide main (or some other function) with memory, so it can use it. In that case you'll just have to delete it later, as in the allocateArray2 method.
This is sometimes what's known as “ownership semantics”, i.e. who owns the object (and therefore who is responsible for freeing the object).
Some functions require the caller to free the returned object, e.g. strdup(), or sometimes the POSIX getline() function too. In these cases, the strdup() and getline() functions can't know what you plan to do with the result or how long you'll need the result for, so they delegate the task of freeing the object to the caller of the function.
Other library functions may return an object whose lifetime is already maintained by the library itself, so there is no need to free anything.
It's important when developing a project to have consistent ownership semantics. For example, perhaps any function that delegates the task of freeing objects could start with alloc (or new or create etc.), and then you'll always know that freeing the result of these functions is your responsibility. It's not really important how the ownership semantics are defined, as long as they are consistent.
Which it is the correct way to release the memory in this case; there is some difference between the two methods?
Both methods are correct.
However, i will prefer to use int* allocateArray2(int size, int value) function which allocates some memory from the heap inside the function and return pointer to allocated memory space.
The primary reason malloc is needed is when you have data that must have a lifetime that is different from code scope. Your code calls malloc in one routine, stores the pointer somewhere and eventually calls free in a different routine.
void allocateArray1(int size, int value) function which asks for some memory, does some processing and frees the memory before returning is not the efficient method if the size is less. You can instead create the array on the stack and use it for further processing. The advantage of using the stack to store variables, is that memory is managed for you. You don't have to allocate memory by hand, or free it once you don't need it any more. What's more, because the CPU organizes stack memory so efficiently, reading from and writing to stack variables is very fast. However, it may cause stack overflow, if you attempt to allocate more memory on the stack than will fit, for example by creating local array variables that are too large.
An example of a very large stack variable in C:
int foo()
{
double x[1048576];
}
The declared array consumes 8 mebibytes of data (assuming each double is 8 bytes); if this is more memory than is available on the stack (as set by thread creation parameters or operating system limits), a stack overflow will occur.
Think of a pointer-datatype, for instance to a floating-pointer number.
typedef float* flPtrt;
How would I allocate an array of 3 elements in the local scope? I guess using malloc and free withing the same scope produces overhead, but what's the alternative?
void foo() {
flPtrt ptr = malloc(sizeof(float)*3);
// ...
free(ptr);
}
If 3 is known at compile time and is small enough, you can declare a local array and use it as a pointer
void foo() {
float array[3];
flPtrt ptr = array;
}
If the size is bigger or variable, you have to use dynamic memory as in your example.
I think what your'e looking for is the alloca() function.
I'm not sure it's standard C, but it exists in GNU, and it worked on my visual studio.
So this is how you use it:
int n = 5;
int* a = (int*) alloca(sizeof(int) * n);
It creates an array of elements on the stack (rather than on the heap with malloc).
Advantages: less overhead, no need to free manually (when you return from your method, the stack folds back and the memory is lost)
Disadvantage: If you want to return a pointer from a method NEVER use alloca, since you will be pointing at something that no longer exists after exiting the function. One can also argue that the stack is usually smaller than the heap, so if you want larger space use malloc.
See more here
If you know the required size of the array ahead of time, you could just allocate it as a stack variable and avoid heap memory management.
Otherwise, the approach you outlined is appropriate and there is not really an alternative.
Use an array.
void foo(void) // note that "void foo()" is obsolete
{
float data[3];
float *ptr = data;
// ...
}
I've read conflicting information on the internet about this. To the best of my knowledge all variables in a function only exist for the life time of the function and so this shouldn't be necessary. But with dynamic pointer arrays I'm not sure.
Thanks
You don't free pointers - they are cleaned up automatically. What you need to free is the memory that was acquired by malloc. You use pointers to access that memory.
Put laconically: Every pointer you get from malloc has to go to free exactly once. Nothing more, nothing less.
It depends on where the memory referenced by the pointer has been allocated.
There are fundamentally 2 ways of allocating space in C.
Using the stack :
void foo(){
int stack_variable = 10;
int *stack_pointer = &stack_variable; //bar shouldn't be freed.
}
Using the heap:
void foo(){
int * heap_pointer = (int *) malloc(sizeof(int)); //heap_pointer need to be freed somewhere
}
In the first case there is no problem: memory allocated in the stack will be released when the function returns. Even if you are using a pointer, and it points to some data in the stack, free isn't necessary. Be careful to not use a pointer to data allocated in the stack when the data itself goes out of scope:
int * foo(){
int stack_variable = 10;
int *ptr = &stack_variable;
return ptr;
}
int * ptr = foo(); // you have a problem here: ptr points to a memory region that no longer exist!
In the second case you are using the heap so you need to use free somewhere, to explicitly release it.
If you have allocated data using malloc/calloc, you need to free the data.
Addition due to curious comment by #Julia Childe:
Well, the point of allocating dynamic memory is that it will remain there till you explicitly free it. This enables you to pass pointers both from and to functions and you are not limited by the scope of a specific function, i.e. main.
Thereby, you can allocate memory for data when you need to and not in advance, thus dynamic memory.
If we did not have this ability, we would have to know how much memory space we would use at compile time.
Hope this clears out some question marks.