C++中使用new进行系统调用分配内存,与C语言中的malloc分配内存的本质区别在于malloc只是在堆上开辟一块内存,而new不但开辟内存而且还调用了对象构造函数进行初始化,最后返回相应指针。
如:A* p = new A;
A* p = new(std::nothrow)A;//如果分配内存失败不抛出异常,返回NULL指针
另外new作为函数可以在指定内存上分配构造对象的。
形式如下:
new (ptr)A();
利用placement new可以在栈上分配对象:
char buff[1024];
memset(buffer, 0, sizeof(buffer));
A* p = new(buff)A();
在网络IO发送一条协议,数据是变长的可能要用到placement new。
比如协议内容如下:
#pragma pack(1)//1字节对其
enum eEventType
{
eEventType_PlayInfo = 1,
eEventType_Max
};
struct stEvent
{
unsigned short eventTyp; //eEventType
stEvent(eEventType _etype) :eventTyp(_etype){}
virtual ~stEvent(){}
};
struct stPlayerInfo
{
stPlayerInfo():stEvent(eEventType_PlayInfo){}
int passward;
char name[32];
int size;
char data[0];
};
可以用
char buffer[1024];
memset(buffer, 0, sizeof(buffer));
stPlayerInfo* pSend = new (buffer)stPlayerInfo();
pSend->passward = 123456;
char someData[] = "hhhh sllll ss";
pSend->size = strlen(someData);
memcpy(pSend->data, someData, pSend->size);
......
//最后将数据发送出去
write(sock, pSend, sizeof(stPlayerInfo)+pSend->size);
其实可以封装一个函数做只是在指定内存调用构造函数
template<class T>
void placement(T* p)
{
new (static_cast<void*>(p))T();
}
这样就可以
char buffer[1024];
memset(buffer, 0, sizeof(buffer));
stPlayerInfo* pSend = (stPlayerInfo*)buffer;
placement(pSend);