Dynamic Memory Allocation Which is best?
I am using following ways to Allocate & Deallocate memory dynamically
1. Using malloc() and free ()
2. Using calloc() and free()
3 using new and delete operator
4 using stl <vector>
Ok all are different styles. But i looking the better performence.During the use of stl allocation application is very slow. Multiple times calling of new and delete will reduce the application efficiency.
On the shadow of these points how i choose a way which give optimum use of CPU. Which is the best on first 3 ways ?
Re: Dynamic Memory Allocation Which is best?
I feel No. 2 is best way!
Re: Dynamic Memory Allocation Which is best?
Quote:
Originally Posted by getzephyr
I feel No. 2 is best way!
The exact opposite is true. No. 2 is not to be used in a C++ program, unless you can justify in using it. It should be the last choice.
How are you going to use No. 2 if you need to create a dynamic array of non-POD types?
Regards,
Paul McKenzie
Re: Dynamic Memory Allocation Which is best?
Quote:
Originally Posted by Dave1024
Ok all are different styles. But i looking the better performence.During the use of stl allocation application is very slow. Multiple times calling of new and delete will reduce the application efficiency.
I can come up with many examples where using new[] and delete[] repeatedly is many times slower than just using a vector and vector.resize().
If you show us what you're doing with vector, I'm sure someone will make recommendations as to what you may be doing that's inefficient. Just saying that something is slow doesn't make it slow -- it could be the programmer that isn't using it efficiently (and correctly) that would make it slow.
Quote:
On the shadow of these points
You need to prove these points to us, before anyone can answer you.
But as I mentioned to the other poster, how are you going to use low-level 'C' functions to dynamically create an array of non-POD types. For example, you can't use malloc() or calloc() here:
Code:
#include <string>
int main()
{
std::string *pString = (std::string*) malloc( 10 * sizeof(std::string));
//...
}
This code is ill-formed and leads to undefined behaviour. The reason is that you have not created 10 strings, i.e. the constructor of the string objects was never called to actually create the objects. Therefore using malloc() or calloc() is not an option. So your original question is invalid if your objects have user-defined constructors.
The only exception to this is if you're going to use placement-new and you need to initially call malloc() to allocate the memory. But you never mentioned placement-new, so I left it out of the discussion.
The bottom line is that you write the program correctly first. If and only if there are bottlenecks do you use dynamically allocated memory. Therefore the first choice would be vector to get the program to work, then making sure you are using vector efficiently before making assumptions that the program is "slow".
Regards,
Paul McKenzie
Re: Dynamic Memory Allocation Which is best?
Reason behind the search for various methods.
char *kk;
kk = new char[1000];
//Array Use (Copy a .txt file content to a .doc file)
delete []kk;
kk = NULL;
When i use this program runs success.Output is OK But compile in VS2005 with warning level 4 I got following message
Leaking memory 'kk' due to an exception. Consider using a local catch block to clean up memory:
Which method will avoid this problem.....
Re: Dynamic Memory Allocation Which is best?
Using std::vector solves that problem. When there´s an exception thrown in the array handling function there will be no cleanup. std::vector will clean up its memory because the vector variable goes out of scope when an exception occurs and its destructor will release the allocated memory. boost::scoped_array may be an alternative.
PS:
vector´s allocation overhead will be neglectible compared to reading a file from disk. Just make sure you don´t have to reallocate multiple times. Resizing the vector to the file´s size before reading into the vector will do only one allocation.
Re: Dynamic Memory Allocation Which is best?
1000 bytes is a small amount. Using the stack looks like a good option:
Code:
char kk[1000];
//Array Use (Copy a .txt file content to a .doc file)
If I remember well, with a 32-bit Windows, the stack can contain up to 2 power 32 or 31 bytes, i.e. 2GB, (EDIT: ) or maybe only 1MB, which is good enough for your 1KB buffer.
Re: Dynamic Memory Allocation Which is best?
I heard stack is used for function calls . LIFO strategy follows. then how i use stack for allocation because 4 or 5 function calls come,the execution become slow ?
Re: Dynamic Memory Allocation Which is best?
Quote:
Originally Posted by Dave1024
I heard stack is used for function calls . LIFO strategy follows. then how i use stack for allocation because 4 or 5 function calls come,the execution become slow ?
Did you measure it? It would be great to see your findings.
Re: Dynamic Memory Allocation Which is best?
Quote:
Originally Posted by Dave1024
Which method will avoid this problem.....
You can follow the compilers recommendation? Or use a vector. Or allocate the array on the stack.
Re: Dynamic Memory Allocation Which is best?
Quote:
Originally Posted by Dave1024
I heard stack is used for function calls . LIFO strategy follows. then how i use stack for allocation because 4 or 5 function calls come,the execution become slow ?
Your worries are based on a misunderstanding. A stack allocated array is not accessed by pushing and popping some stack. It's accessed the same way as a heap allocated array. And the actual allocation of a stack array is faster.
Re: Dynamic Memory Allocation Which is best?
Quote:
Originally Posted by Dave1024
I heard stack is used for function calls . LIFO strategy follows. then how i use stack for allocation because 4 or 5 function calls come,the execution become slow ?
When you push something onto the stack, it does NOT copy existing items around within the stack, instead it just uses the next free bytes on the stack. So LIFO is very fast.
Re: Dynamic Memory Allocation Which is best?
Hmm, usually I agree with Paul...
What would be the worst case scenario? Having to allocate large quantities of objects with very short lifetime. How to most effectively obtain that? Reuse allocations!!!
vector.resize()???? Common,... no way!!!
new[] and delete[]... in the end, those compilers I've been working with were still calling malloc() and free()... so why not have more control over the code? I'm not ready yet to convert all my codebase to C# or other managed language!
My solution... a simple pool of reusable chunks of memory, and these are the steps:
- malloc() an aligned chunk of memory capable to store a reasonable number of objects; working with segments seems to be still the best solution, since heap managers commit pages in a similar way; it is recommended to limit these allocations to a lower value than the total virtual memory available; when initialization with zero is required, do not use calloc(); might be "evil" :D ; I prefer ZeroMemory(), but memset() might have almost same performance
- use placement new to construct objects of a non-POD type, using pre-allocated memory; it should work as a simple pool and if required, thread-safe; when the pool has memory to reuse, the new instance is constructed at the same address where a released object was, thus reusing the memory; when the pool has no more available chunks, allocate one more, if within the limits designed
- releasing an object consists in calling the destructor of the class, marking the memory as available, and discarding the belonging chunk if completely released
Variations of the above design work better in specific scenarios, but the main idea remains the same. There're many advantages to these kind of implementations, and these I consider the most important:
- avoiding memory fragmentation
- less work for your heap manager which cannot assume which objects being allocated have the same size with previously deleted ones; which of the 2 following loops is faster?
Code:
register unsigned int idx;
int * p = static_cast<int*>(malloc(256 * sizeof(int)));
idx = 1000000;
while (idx) { --idx;
int& c = * new(&p[idx & 0xFF]) int;
c = idx & 0xFF;
// c.~int(); // int doesn't have a destructor, but non-POD types have
}
::free(p);
Code:
register unsigned int idx;
idx = 1000000;
while (idx) { --idx;
int& c = * new int;
c = idx & 0xFF;
delete &c;
}
Regards,
Re: Dynamic Memory Allocation Which is best?
Quote:
Originally Posted by Bornish
Hmm, usually I agree with Paul...
What would be the worst case scenario? Having to allocate large quantities of objects with very short lifetime. How to most effectively obtain that? Reuse allocations!!!
That is not really the example I'm referring to.
What I'm refering to are the classes that persons create that attempt to do their own memory resizing. For example:
Code:
class foo
{
char *ptr;
public:
void resize(unsigned int num)
{
char *temp = new char [num];
delete [] ptr;
ptr = temp;
}
};
How many times have you seen code written like this? In this case, it is a simple char*, but in other cases it could be any object. Replacing the naive version of resize() with a vector<char> and calling vector::resize() is defacto faster, since vector.resize() doesn't reallocate if it doesn't have to.
Regards,
Paul McKenzie
Re: Dynamic Memory Allocation Which is best?
On the other hand, it's not all that difficult to write your own resize function which uses essentially the same algorithm as vector::resize. If you want to do that you can. Still, if you aren't limited to C code, there's little reason *not* to use a std::vector if you can.