- #include <cstdio>
- #include <cstdlib>
- #include <vector>
- #include <string>
- #include <iostream>
- using namespace std;
- typedef string QString;
- /** Class Exception
- * An Exception similar to that of Java.
- */
- class Exception{
- public:
- Exception(const QString &pReason):reason(pReason){}
- Exception(const char *pReason) {
- reason=pReason;
- }
- QString what(){ return reason; }
- QString reason;
- };
- /** This memory pool is designed to be 'multi-allocate, release once'.
- * As this is also the right feature of memory usage in a sniffer.
- */
- class PacketPool {
- static vector<unsigned char*> units;
- static size_t sizeLeftInUnit;
- static unsigned char *currentPosition;
- public:
- inline void * operator new(size_t);
- inline void operator delete(void*);//Actually this will not be used.
- static void releasePool();
- };
- //const size_t POOL_UNIT_SIZE =2097152; //2M size
- const size_t POOL_UNIT_SIZE =100; //Small size for test
- vector<unsigned char*> PacketPool::units;
- size_t PacketPool::sizeLeftInUnit =0;
- unsigned char* PacketPool::currentPosition =NULL;
- //Exceptions are thrown in such cases:
- //1.Value parameter 'size' is bigger than POOL_UNIT_SIZE
- //2.Not enough memory for new pool unit.
- inline void * PacketPool::operator new (size_t size) {
- if(size > POOL_UNIT_SIZE) {
- Exception e("Size too big for a pool unit");
- throw e;
- }
- if(sizeLeftInUnit <size) { //If not enough, just expand it!
- printf("Expanding pool...\\n");
- unsigned char *unit =(unsigned char*)malloc(POOL_UNIT_SIZE);
- if(!unit) {
- Exception e("Not enough memory for new packets");
- throw e;
- }
- units.push_back(unit);
- currentPosition =unit;
- sizeLeftInUnit =POOL_UNIT_SIZE;
- printf("Expanding pool !Pool Address :%x",(unsigned int)currentPosition);
- }
- //Allocation
- sizeLeftInUnit -=size;
- unsigned char* oldPosition =currentPosition;
- currentPosition +=size;
- return oldPosition;
- }
- inline void PacketPool::operator delete(void *) {
- PacketPool::releasePool();
- }
- void PacketPool::releasePool() {
- vector<unsigned char*> ::iterator iter =units.begin();
- while(iter !=units.end() ) {
- free(*iter);//If you use delete here it will be nested call!
- iter =units.erase(iter);
- }
- currentPosition =NULL;
- printf("Release Pool Complete\\n");
- }
- class Packet :public PacketPool{
- char a[1001];
- public:
- Packet() {}
- };
- int main() {
- Packet *a[10];
- try{
- for(int i=0;i<10;i++) {
- a[i]=new Packet();
- printf("\\nAllocated Address :%x\\n",(unsigned int)a[i]);
- }
- PacketPool::releasePool();
- }catch(Exception &e) {
- cout<<e.what()<<endl;
- }
- return 0;
- }
- //该片段来自于http://www.codesnippet.cn/detail/170520133438.html
来源: http://www.codesnippet.cn/detail/170520133438.html