标签:
测试用例还不够,希望有大虾测测 反馈意见。该程序还把线程锁,自动锁及operator new重载实现了下,测试没问题。#include <iostream> #include <stdlib.h> #include <stdio.h> #include <time.h> #include <new> #include <string.h> using namespace std; #ifdef WIN32 #include <windows.h> #else #include <pthread.h> #endif using namespace std; /* 多线程锁,同一个线程尽管锁住也可以访问临界资源 */ class myThreadLock { public: myThreadLock(); ~myThreadLock(); void Lock(); void unLock(); private: #ifdef WIN32 CRITICAL_SECTION win_critical_section; #else pthread_mutex_t linux_mutex; #endif }; void myThreadLock::Lock() { #ifdef WIN32 EnterCriticalSection(&win_critical_section); #else pthread_mutex_lock(&linux_mutex); #endif } void myThreadLock::unLock() { #ifdef WIN32 LeaveCriticalSection(&win_critical_section); #else pthread_mutex_unlock(&linux_mutex); #endif } myThreadLock::myThreadLock() { #ifdef WIN32 InitializeCriticalSection(&win_critical_section); #else pthread_mutex_init(&linux_mutex, NULL); #endif } myThreadLock::~myThreadLock() { #ifdef WIN32 DeleteCriticalSection(&win_critical_section); #else pthread_mutex_unlock(&linux_mutex); #endif } /* 自动解锁类 */ class AutoMutex { public: AutoMutex(myThreadLock *lock) { pThreadLock = lock; if(pThreadLock != NULL) pThreadLock->Lock(); } ~AutoMutex() { if(pThreadLock != NULL) pThreadLock->unLock(); } private: myThreadLock* pThreadLock; }; /************************************************* (1)小内存: pUsedList[]: [8] [16] [32] [64] [128]...... ↓ ↓ ↓ ↓ ↓ [8] [16] [32] [64] [128]...... ↓ ↓ ↓ ↓ ↓ [8] [16] [32] [64] [128] ....... pFreeList[]: [8] [16] [32] [64] [128]...... ↓ ↓ ↓ ↓ ↓ [8] [16] [32] [64] [128]...... ↓ ↓ ↓ ↓ ↓ [8] [16] [32] [64] [128] ....... (2)大内存: 链表结构: pBlockListHead[0]<->block1[size1]<->block2[size2]<->......... 分配内存: 大的内存块由一个双向链表来管理,每次分配找到一个空闲节点A, 判断该空闲节点A 的size是否满足需要分配的大小,如果该节点A 分 配完以后还有剩余大于或等于最小blockSize 则新建个节点B,然后把该 节点A 的使用标志置为1,新建节点B 的大小为A 节点分配后剩余的内存空间大小。 释放内存: 找到要释放的内存地址相符的节点,将该节点的使用标志置为0, 同时判断该节点的前后节点是否被使用,如果没有被使用则将前后没被使用的节点 合并为一个节点使该节点的size更大,小的内存得以回收。 *************************************************/ #define BIG_MEMORY_SIZE (5 * 1024 * 1024) //5 M #define SMALL_MEMORY_MAX_SIZE (1024) #define BIG_MEMORY_BLOCK_MAX_NUM ((BIG_MEMORY_SIZE) / (SMALL_MEMORY_MAX_SIZE + 4)) typedef struct smNode { void* start_addr; struct smNode *next; }SmNode, *pSmNode; /* small memroy list struct */ typedef struct SmBlockList { pSmNode pUsedList; pSmNode pFreeList; void **pBlockFirstAddr; /* 保存小内存池各个档次size 所分配内存的起始地址 */ unsigned int *pBlockSize; /* 小内存池各个档次size 分配内存的总大小 */ }st_SmBlockList; typedef struct bigNode { void* start_addr; unsigned int size; unsigned char usedFlag; //unsigned char reserved[3]; struct bigNode *next; struct bigNode *prev; }BigNode, *pBigNode; #define TEST_BIGMM (0) /* Test the big memory alloc */ /* big memory list struct */ typedef struct BigBlockList { pBigNode pBlockListHead; pBigNode pSearchStartNode; unsigned int blockCount; //当前已使用和未使用的block个数 #if TEST_BIGMM /* for test */ unsigned int remainSize; //所有未被使用的总内存 unsigned int unUsedBlockNum; //当前未被使用的block的个数 #endif unsigned int minSizePerBlock; //每个block最小的分配size }st_BigBlockList; /* 小内存各档次size定义,最后一个用于分配大内存链表节点 */ enum { SML_8 = 8, SML_16 = 16, SML_32 = 32, SML_64 = 64, SML_128 = 128, SML_256 = 256, SML_512 = 512, SML_1024 = 1024, BIG_NODE = sizeof(BigNode) /* 大内存链表节点大小 */ }; /* 小内存各档次节点数 */ enum { SML8_N = 3000, SML16_N = 3000, SML32_N = 3000, SML64_N = 3000, SML128_N = 3000, SML256_N = 1500, SML512_N = 1500, SML1024_N = 1500, BIGNODE_N = BIG_MEMORY_BLOCK_MAX_NUM + 1 }; /* 存储小内存各档次大小数组定义 */ static int s_small_memory_size[] = {SML_8, SML_16, SML_32, SML_64, SML_128, SML_256, SML_512, SML_1024, BIG_NODE}; //bytes /* 存储小内存各档次节点数数组定义 */ static int s_small_memory_num[] = {SML8_N, SML16_N, SML32_N, SML64_N, SML128_N, SML256_N, SML512_N, SML1024_N, BIGNODE_N}; class MemoryManage //内存管理 { public: MemoryManage(); ~MemoryManage(); void* Malloc(size_t size); void Free(void* addr); pBigNode GetBigListHead() const; private: void BigMemInit(); void BigMemDeInit(); void* MallocBigMemory(size_t size); void FreeBigMemory(void* addr); void SmlMemInit(); void SmlMemDeInit(); void* GetFreeSmNode(int index); /*move the smNode from freeList to usedList; and return pSmNode->start_addr */ void RetUsedSmNode(int index, void* addr); /* move the smNode from usedList to freeList */ void* MallocSmlMemory(size_t size); void FreeSmlMemory(void* addr); void* firstAddr; void* smlListFirstAddr; int total_small_list_head; int total_small_node_num; int total_big_size; void* bigMmFirstAddr; st_SmBlockList sm_block_list; st_BigBlockList bg_block_list; myThreadLock smLock; /**< 小内存分配线程锁*/ myThreadLock bgLock; /**< 大内存分配线程锁*/ }; /* 构造函数初始化内存池 */ MemoryManage::MemoryManage() { int total_small_size = 0, big_size = 0, small_node_num = 0; int i = 0; /* 小内存总链表数 */ total_small_list_head = sizeof(s_small_memory_size) / sizeof(s_small_memory_size[0]); for(; i < total_small_list_head; ++i) { total_small_size += s_small_memory_size[i] * s_small_memory_num[i]; small_node_num += s_small_memory_num[i]; } total_small_node_num = small_node_num; /* 4字节对齐 */ total_big_size = ((BIG_MEMORY_SIZE) & (~(sizeof(int) - 1))) + sizeof(int); total_small_size = (total_small_size & (~(sizeof(int) - 1))) + sizeof(int); cout << "small node total num = " << total_small_node_num << endl; cout << "total small size: " << total_small_size; cout << "; total big size: " << total_big_size << endl; /* System malloc all memory */ firstAddr = malloc(total_small_size + total_big_size); if(firstAddr == NULL){ cout << "malloc all memory fail!" << endl; exit(-1); } bigMmFirstAddr = (unsigned char*)firstAddr + total_small_size; smlListFirstAddr = NULL; /* create small memory list */ SmlMemInit(); /* create big memory list */ BigMemInit(); } /* 析构函数释放内存池 */ MemoryManage::~MemoryManage() { BigMemDeInit(); /* free list */ SmlMemDeInit(); total_big_size = 0; bigMmFirstAddr = NULL; if(firstAddr != NULL){ free(firstAddr); firstAddr = NULL; } } /* 对外提供的Malloc 接口 */ void* MemoryManage::Malloc(size_t size) { void* addr = NULL; if(size <= 0 || size > total_big_size) return NULL; /* 如果需要分配的size 大于等于 大内存每个block的最小size */ if(size >= bg_block_list.minSizePerBlock) { /* 锁住 */ AutoMutex auto_mutex(&bgLock); //cout << "malloc big memory!" << endl; return MallocBigMemory(size); } else { /* 锁住 */ AutoMutex auto_mutex(&smLock); //cout << "malloc i = " << i << endl; return MallocSmlMemory(size); } return addr; } /* 对外提供的Free 接口 */ void MemoryManage::Free(void* addr) { if(addr == NULL) return; if(addr >= bigMmFirstAddr) { /* 锁住 */ AutoMutex auto_mutex(&bgLock); //cout << "free big memory!" << endl; FreeBigMemory(addr); } else { /* 锁住 */ AutoMutex auto_mutex(&smLock); FreeSmlMemory(addr); } return; } /* 获得大内存链表头节点 */ pBigNode MemoryManage::GetBigListHead() const { return bg_block_list.pBlockListHead; } /* 管理大内存的链表初始化 */ void MemoryManage::BigMemInit() { bg_block_list.blockCount = 1; pBigNode pHead = (pBigNode)GetFreeSmNode(total_small_list_head - 1); if(pHead == NULL) { cout << "BigMemInit() malloc pHead error!!!!" << endl; exit(-1); } bg_block_list.pBlockListHead = pHead; pHead->size = 0; pHead->start_addr = NULL; pHead->usedFlag = 1; pHead->prev = NULL; pBigNode pNew = (pBigNode)GetFreeSmNode(total_small_list_head - 1); if(pNew == NULL) { cout << "BigMemInit() malloc pNew error!!!!" << endl; exit(-1); } pNew->next = NULL; pNew->size = total_big_size; pNew->start_addr = bigMmFirstAddr; pNew->usedFlag = 0; pHead->next = pNew; pNew->prev = pHead; bg_block_list.pSearchStartNode = pNew; #if TEST_BIGMM bg_block_list.unUsedBlockNum = 1; bg_block_list.remainSize = total_big_size; #endif bg_block_list.minSizePerBlock = (SMALL_MEMORY_MAX_SIZE & (~(sizeof(int) - 1))) + sizeof(int); return; } /* 归还大内存链表节点的内存空间 */ void MemoryManage::BigMemDeInit() { pBigNode pCur = bg_block_list.pBlockListHead; while(pCur) { pBigNode pTmp = pCur; pCur = pCur->next; RetUsedSmNode(total_small_list_head - 1, pTmp); pTmp = NULL; } cout << "*************** BigMemDeInit Success !!!*******************" << endl; } void* MemoryManage::MallocBigMemory(size_t mem_size) { size_t size = mem_size; /* 判断开始搜索的节点块大小是否满足要求 */ if((bg_block_list.pSearchStartNode->size < size) || (bg_block_list.pSearchStartNode->usedFlag == 1)) bg_block_list.pSearchStartNode = bg_block_list.pBlockListHead->next; //如果不满足则从头开始寻找 size_t sTmp = mem_size; pBigNode pCur = bg_block_list.pSearchStartNode; while(1) { if(pCur != NULL ) { if(size < bg_block_list.minSizePerBlock){ size = bg_block_list.minSizePerBlock; } if((pCur->usedFlag == 0) && (pCur->size >= size)) { if((pCur->size - size) >= bg_block_list.minSizePerBlock) { pBigNode pNew = (pBigNode)GetFreeSmNode(total_small_list_head - 1); if(pNew == NULL){ cout << "********************************" << endl; return NULL; } /* 一片大内存区域最多只能 形成BIG_MEMORY_BLOCK_MAX_NUM 块区域 */ bg_block_list.blockCount++; if(bg_block_list.blockCount > BIG_MEMORY_BLOCK_MAX_NUM){ cout << "@@@@@@@@@@@@@@@@@@@@@@@" << endl; return NULL; } pNew->next = pCur->next; if(pCur->next != NULL) pCur->next->prev = pNew; pNew->size = pCur->size - size; pNew->start_addr = (unsigned char*)pCur->start_addr + size; pNew->usedFlag = 0; pCur->usedFlag = 1; pCur->next = pNew; pNew->prev = pCur; pCur->size = size; bg_block_list.pSearchStartNode = pNew; #if TEST_BIGMM bg_block_list.remainSize -= size; #endif return pCur->start_addr; } else { pCur->usedFlag = 1; #if TEST_BIGMM bg_block_list.unUsedBlockNum--; bg_block_list.remainSize -= size; #endif return pCur->start_addr; } } else { pCur = pCur->next; } } else break; } cout << "Return NULL#########, sTmp = " << sTmp << ";size= " << size << endl; return NULL; } void MemoryManage::FreeBigMemory(void* addr) { pBigNode pCur = bg_block_list.pBlockListHead->next; while(1) { if(pCur == NULL){ cout << "free big memory error!!! " << endl; break; } if((pCur->usedFlag == 1) && (pCur->start_addr == addr)) { #if TEST_BIGMM bg_block_list.remainSize += pCur->size; #endif /* free该节点时,判断它后面的节点是否被使用,如果未被使用则把它们合并成一个大内存块(内存碎片回收) */ pBigNode pBack = pCur->next; pBigNode pPrev = pCur->prev; while((pBack != NULL) && (pBack->usedFlag == 0)) { pCur->next = pBack->next; if(pBack->next != NULL) pBack->next->prev = pCur; pCur->size += pBack->size; pBigNode pfree = pBack; pBack = pBack->next; if(bg_block_list.pSearchStartNode == pfree){ bg_block_list.pSearchStartNode = pCur; } RetUsedSmNode(total_small_list_head - 1 ,pfree); /* free node */ pfree = NULL; bg_block_list.blockCount--; #if TEST_BIGMM bg_block_list.unUsedBlockNum--; #endif } /* free该节点时,判断它前面的节点是否被使用,如果未被使用则把它们合并成一个大内存块(内存碎片回收) */ while((pPrev != NULL) && (pPrev->usedFlag == 0)) { pCur->prev = pPrev->prev; if(pPrev->prev != NULL) pPrev->prev->next = pCur; pCur->size += pPrev->size; pCur->start_addr = pPrev->start_addr; pBigNode pfree = pPrev; pPrev = pPrev->prev; if(bg_block_list.pSearchStartNode == pfree){ bg_block_list.pSearchStartNode = pCur; } RetUsedSmNode(total_small_list_head - 1 ,pfree); /* free node */ pfree = NULL; bg_block_list.blockCount--; #if TEST_BIGMM bg_block_list.unUsedBlockNum--; #endif } pCur->usedFlag = 0; #if TEST_BIGMM bg_block_list.unUsedBlockNum++; #endif return; } else pCur = pCur->next; } return; } /* 小内存池链表的建立及初始化 */ void MemoryManage::SmlMemInit() { /* 建立各个档次链表的头节点 */ smlListFirstAddr = malloc(total_small_list_head * 2 * sizeof(SmNode) /* total small memory list head space */ + total_small_node_num * sizeof(SmNode)); /* total small memory list node space*/ if(smlListFirstAddr == NULL) { cout << "malloc smlListFirstAddr fail!!! " << endl; exit(-1); } void* smListNodeAddr = smlListFirstAddr; memset(smListNodeAddr, 0, sizeof(SmNode) * total_small_list_head * 2); sm_block_list.pFreeList = (pSmNode)smListNodeAddr; sm_block_list.pUsedList = (pSmNode)(sm_block_list.pFreeList + total_small_list_head); sm_block_list.pBlockSize = (unsigned int*)malloc(sizeof(unsigned int) * total_small_list_head); if(sm_block_list.pBlockSize == NULL){ cout << "malloc pBlockSize error!!" << endl; exit(-1); } memset(sm_block_list.pBlockSize, 0, sizeof(unsigned int) * total_small_list_head); sm_block_list.pBlockFirstAddr = (void**)malloc(sizeof(void*) * total_small_list_head); if(sm_block_list.pBlockFirstAddr == NULL){ cout << "malloc blockfirst addr error!!" << endl; exit(-1); } memset(sm_block_list.pBlockFirstAddr, 0, sizeof(void*) * total_small_list_head); pSmNode pNodeAddr = (pSmNode)smListNodeAddr + total_small_list_head * 2; /* create small memory list */ int count = 0, i = 0; for(i = 0; i < total_small_list_head; ++i) { int j = 0; static int preCount = 0; pSmNode pTmp = &sm_block_list.pFreeList[i]; sm_block_list.pFreeList[i].next = NULL; sm_block_list.pFreeList[i].start_addr = NULL; for(j = 0; j < s_small_memory_num[i]; ++j) { pSmNode pNew = pNodeAddr; ++pNodeAddr; pNew->start_addr = (unsigned char*)firstAddr + count; pNew->next = NULL; count += s_small_memory_size[i]; pTmp->next = pNew; pTmp = pNew; } sm_block_list.pBlockSize[i] = count - preCount; preCount = count; sm_block_list.pBlockFirstAddr[i] = sm_block_list.pFreeList[i].next->start_addr; } return; } void MemoryManage::SmlMemDeInit() { free(sm_block_list.pBlockSize); sm_block_list.pBlockSize = NULL; free(sm_block_list.pBlockFirstAddr); sm_block_list.pBlockFirstAddr = NULL; free(smlListFirstAddr); smlListFirstAddr = NULL; cout << "*************** SmlMemDeInit Success !!!*******************" << endl; } /* 获得小内存池第index 个的free 链表的节点 并将该节点标记为used, 转移到used 链表中去*/ void* MemoryManage::GetFreeSmNode(int index) { if(index >= total_small_list_head) { cout << "invail index !!!!!!!!" << endl; return NULL; } int i = index; void* addr = sm_block_list.pFreeList[i].next->start_addr; pSmNode ptmp = sm_block_list.pFreeList[i].next; sm_block_list.pFreeList[i].next = sm_block_list.pFreeList[i].next->next; if(ptmp == sm_block_list.pUsedList[i].next) { cout << "very fatal error!!!! ptmp == sm_block_list.pUsedList[i].next" << endl; exit(-1); } ptmp->next = sm_block_list.pUsedList[i].next; sm_block_list.pUsedList[i].next = ptmp; return addr; } /* 将节点从used 链表转移到free 链表中去 */ void MemoryManage::RetUsedSmNode(int index, void* addr) { if(index >= total_small_list_head) { cout << "invail index !!!!!!!!" << endl; return; } int i = index; pSmNode pCur = sm_block_list.pUsedList[i].next; pSmNode pPre = &sm_block_list.pUsedList[i]; while(1) { if(pCur == NULL) break; if(pCur->start_addr == addr) break; pPre = pCur; pCur = pCur->next; if(pPre == pCur){ cout << "firstAddr = " << firstAddr << ", pCurAddr = " << pCur->start_addr << endl; exit(-1); } //cout << "free small memory find node, pCur = " << pCur << endl; } if(pCur != NULL) { pPre->next = pCur->next; pCur->next = sm_block_list.pFreeList[i].next; sm_block_list.pFreeList[i].next = pCur; } else { cout << "i = " << i << " free small memory fail!!!!!" << endl; } return; } void* MemoryManage::MallocSmlMemory(size_t size) { int i = 0; for(; i < total_small_list_head - 1; i++) { if(size <= s_small_memory_size[i]) break; } while(1) { /* if this size free list have free node */ if(sm_block_list.pFreeList[i].next != NULL){ break; } else{ /* if this size free list doesn't have free node, then go to search big size free list */ ++i; if(i >= total_small_list_head - 1){ /* if all big size free list is used */ cout << "small freeList is FULL!!!!!!!!!!!" << endl; return NULL; } } } return GetFreeSmNode(i); } void MemoryManage::FreeSmlMemory(void *addr) { int i = 0; for(; i < total_small_list_head - 1; i++) { if((addr >= sm_block_list.pBlockFirstAddr[i]) && (addr < (unsigned char*)sm_block_list.pBlockFirstAddr[i] + sm_block_list.pBlockSize[i])){ break; } } RetUsedSmNode(i, addr); return; } static MemoryManage mm_instance; void* myMalloc(size_t size) { return mm_instance.Malloc(size); } void myFree(void* addr) { mm_instance.Free(addr); return; } class D { public: D() : n(1), str("hello") { cout << "D() call" << endl; } ~D(); void* operator new(size_t size); // operator new 设计自己分配内存的方式 void operator delete(void *addr); void* operator new[](size_t size); void operator delete[](void *addr); void* operator new(size_t, void* addr); // placement new, 参数addr为已知的内存分配地址,设计调用构造函数初始化这个内存 void operator delete(void* mem, void* addr); void setValue(int m) { n = m; } private: int n; string str; }; D::~D() { cout << "~D() call" << endl; } void* D::operator new(size_t size) { cout << "D::operator new call!!!, size = " << size << endl; return mm_instance.Malloc(size); } void D::operator delete(void *addr) { cout << "D::operator delete call!!!" << endl; mm_instance.Free(addr); return; } void* D::operator new[](size_t size) { cout << "D::operator new[] call!!!, size = " << size << endl; return mm_instance.Malloc(size); } void D::operator delete[](void *addr) { cout << "D::operator delete[] call!!!" << endl; mm_instance.Free(addr); return; } void* D::operator new(size_t size, void* addr) { cout << "D::operator placement new call!!!" << endl; ::operator new(size, addr); return addr; } void D::operator delete(void* mem, void* addr) { cout << "D::operator placement delete call!!!" << endl; ::operator delete(mem); return; } /******************************************************/ int main() { cout << sizeof(int) << endl; cout << sizeof(SmNode) << "," << sizeof(BigNode) << endl; cout << sizeof(st_SmBlockList) << "," << sizeof(st_BigBlockList) << endl; /*********************** memory magement test********************************/ clock_t start = clock(); int l = 0; for(l = 0; l < 100000; l++) { /* my memory management */ int *ar = (int*)myMalloc(sizeof(int) * 10); if(ar == NULL) cout << "myMalloc ar fail!!!" << endl; myFree(ar); } float end = float(clock() - start)/CLOCKS_PER_SEC; cout << "(1) time is " << end << "seconds." << endl; // 0.028 s start = clock(); for(l = 0; l < 100000; l++) { /* my memory management */ int *ar = (int*)malloc(sizeof(int) * 10); if(ar == NULL) cout << "malloc fail!!!" << endl; free(ar); } end = float(clock() - start)/CLOCKS_PER_SEC; cout << "(2) time is " << end << "seconds." << endl; // 0.032 s /* 测试随机分配 随机释放内存 100万次 */ char* parr[1024] = {NULL}; srand(time(NULL)); start = clock(); int failcount = 0; for(l = 0; l < 1000000; l++) { static unsigned int i = 0; int rand_index = 0; rand_index = rand() % 1024; int rand_size = rand() % 5120 + 1025; rand_size &= (~3); rand_size += 4; char *ai = (char*)myMalloc(sizeof(char) * rand_size); if(!ai){ cout << "(1) malloc ai fail!!!" << endl; #if 1 pBigNode b = mm_instance.GetBigListHead()->next; int unUsed = 0; int total = 0; while(b->next != NULL){ if(b->usedFlag == 0) unUsed++; b = b->next; ++total; } cout << "total count = " << total << " unUsed count = " << unUsed << endl; #endif failcount++; } if(parr[rand_index] != NULL){ myFree(parr[rand_index]); parr[rand_index] = NULL; } parr[rand_index] = ai; ++i; if(i % 1000 == 0){ //cout << i << endl; } if(i >= 0xffffffff) i = 0; rand_index = rand() % 1024; myFree(parr[rand_index]); parr[rand_index] = NULL; } end = float(clock() - start)/CLOCKS_PER_SEC; cout << "(3) time is " << end << "seconds." << endl; // 2.768 s cout << "Fail NUM: " << failcount << endl; for(l = 0; l < 1024; l++){ if(parr[l] != NULL){ myFree(parr[l]); parr[l] = NULL; } } start = clock(); for(l = 0; l < 1000000; l++) { static unsigned int i = 0; int rand_index = 0; rand_index = rand() % 1024; int rand_size = rand() % 5120 + 1025; rand_size &= (~3); rand_size += 4; char *ai = (char*)malloc(sizeof(char) * rand_size); if(!ai){ cout << "(1) malloc ai fail!!!; SIZE = " << rand_size << endl; } if(parr[rand_index] != NULL){ free(parr[rand_index]); parr[rand_index] = NULL; } parr[rand_index] = ai; ++i; if(i % 1000 == 0){ //cout << i << endl; } if(i >= 0xffffffff) i = 0; rand_index = rand() % 1024; free(parr[rand_index]); parr[rand_index] = NULL; } end = float(clock() - start)/CLOCKS_PER_SEC; cout << "(4) time is " << end << "seconds." << endl; // 0.746 s char* ptmp = (char*)myMalloc(sizeof(char) * 960 * 540); myFree(ptmp); ptmp = NULL; /* operator new 和 delete 的重载 */ D *dp = new D; delete dp; void *ddp = malloc(sizeof(D)); D *dvp = new (ddp) D; //调用placement new 在已获得的内存空间中构造一个D对象 dvp->~D(); D *dap = new D[10]; dap[3].setValue(100); delete [] dap; return 0; }
标签:
原文地址:http://blog.csdn.net/u010312436/article/details/51437126