昨天有同事問到可不可以讓物件 new 在 share memory 裡面,我跟他說 c++ 的 new 可以像下面例子這樣用,但是他後來沒試。好吧,反正我以前也沒試過,就寫了個小程式試一下:
/** * Filename: test_new.cpp * Description: Test new(storage) Person(); */ #include <cstdlib> #include <string> #include <iostream> class Person { public: Person() {} ~Person() {} std::string getName() { return _name; }; void setName( std::string name ) { _name=name; } std::string toString() { return _name; } private: std::string _name; }; int main( int argc, char* argv[] ) { char* storage = (char*)malloc( 1024 ); // allocate 1K Person* person = new(storage) Person(); person->setName( "anonymous" ); std::cout << person->toString() << std::endl; // if just storage, person will be replaced by intArray. (2) // int* intArray = new(storage) int[10]; int* intArray = new(storage+sizeof(person)) int[10]; int i=0; // assign value. for( i=0; i<10; i++ ) intArray[i] = i; // show the values for( i=0; i<10; i++ ) printf( "%d ", intArray[i]); printf("\n"); // dump storage char* iter=storage; printf("=== begin dump ===\n"); i=0; while( i!=512 ) { printf( "%02x ", (unsigned char)*iter ); iter++; i++; if( !(i%16) ) printf( "\n" ); } printf("=== end dump ===\n"); printf( "person address = %08x intArray address = %08x\n", (unsigned int)person, (unsigned int)intArray ); // cannot delete, it cause segmentation fault. (1) //delete person; //delete[] intArray; // but we can use free. free( storage ); }
結論:
- new(storage) Person() 實際上是 new 在 storage 這塊空間裡面,所以之後如果呼叫 delete,會出錯。
- 如果不累加 storage 的話,會把之前配置的空間覆蓋掉。
- malloc() 可以用 shmget()、shmat() 代替,沒有問題。
- 以上面的例子,std::string 會配置一塊空間來放字串,這塊空間並不在 storage 裡面,使用時要注意。如果要這樣用,應該要再取代掉 STL allocator 的機制。