Memory Programming Assignment 4 Points each (allocate, release, release_all) 1- Allocate a memory pool of Stock objects. 2- Show object allocation and de-allocation. 3- Code up allocate_from_pool(), release(), and release_all(). NOTE: The memory pool class could be inherited by Stock There are many ways to code up a memory pool Some people use STL to code up the pool // main.cpp -- uses the Stock class // compile with stock.cpp #include using std::cout; using std::cin; using std::endl; using std::ios_base; #include "stock.h" const int STKS = 4; int main() { // create an array of initialized objects Stock *stocks[STKS] = { new Stock("NanoSmart", 12, 20.0), new Stock("Boffo Objects", 200, 2.0), new Stock("Monolithic Obelisks", 130, 3.25), new Stock("Fleep Enterprises", 60, 6.5) }; cout.precision(2); // #.## format cout.setf(ios_base::fixed, ios_base::floatfield);// #.## format cout.setf(ios_base::showpoint); // #.## format cout << endl; cout << "Stock holdings:\n"; int st; for (st = 0; st < STKS; st++) cout << *stocks[st]; Stock top = *stocks[0]; for (st = 1; st < STKS; st++) top = top.topval(*stocks[st]); cout << "\nMost valuable holding:\n"; cout << top; cout << endl; // free stock objects for (st = 0; st < STKS; st++) { delete stocks[st]; cout << endl; } // release stock memory pool memory Stock::release_all() ; return 0; } // stock.h -- augmented version that uses memory pool for Stock objects #ifndef STOCK_H_ #define STOCK_H_ #include using std::ostream; class Stock { public: Stock(); // default constructor Stock(const char * co, int n = 0, double pr = 0.0); Stock(const Stock& stock); // copy constructor ~Stock(); // destructor // Overrides for new and delete to implement memory pooling static void* operator new (size_t size); static void operator delete (void* p); static void release_all(); // overloaded operator methods Stock & operator=(const Stock & stock); // overloaded friend operators friend ostream & operator<<(ostream & os, const Stock & stock); // accessor methods // return string representing company const char* get_company() const { return company; } // return total number of shares int get_shares() const { return shares; } // return share value double get_share_val() const { return share_val; } // return total value of all shares double get_total_val() const { return total_val; } void buy(int num, double price); void sell(int num, double price); void update(double price); const Stock & topval(const Stock & s) const; private: void set_tot() { total_val = shares * share_val; } // memory pool enum enum { MAX_POOL_MEMORY = 5 }; // memory pool methods static void release(void* p); static void* allocate_from_pool(size_t size); // memory pool variables static bool empty; // index of the next available free memory location in the pool static int indexNextFreeLocation; static void* pool[MAX_POOL_MEMORY]; char *company; // pointer to internal string buffer int len; // length of string int shares; double share_val; double total_val; }; #endif // stock.cpp #include #include #include "stock.h" #include // for std::bad_alloc using std::bad_alloc; using std::cout; using std::endl; using std::cerr; // static Globals bool Stock::empty = true; int Stock::indexNextFreeLocation = 0; void* Stock::pool[MAX_POOL_MEMORY]; // constructors // default constructor Stock::Stock() { len = strlen("no name"); company = new char [len + 1]; strcpy(company, "no name"); shares = 0; share_val = 0.0; total_val = 0.0; } // constructor with parameters Stock::Stock(const char * company, int shares, double price) { len = strlen(company); company = new char [len + 1]; strcpy(this->company, company); if (shares < 0) { std::cerr << "Number of shares can't be negative; " << company << " shares set to 0.\n"; this->shares = 0; } else this->shares = shares; share_val = price; set_tot(); } // copy constructor Stock::Stock(const Stock & stock) { len = strlen(stock.get_company()); company = new char [len + 1]; strcpy(company, stock.get_company()); shares = stock.get_shares(); share_val = stock.get_share_val(); set_tot(); } // overloaded operator methods // assignment operator Stock & Stock::operator=(const Stock & stock) { if (this == &stock) return *this; delete [] company; len = strlen(stock.get_company()); company = new char [len + 1]; strcpy(company, stock.get_company()); shares = stock.get_shares(); share_val = stock.get_share_val(); set_tot(); return *this; } // class destructor Stock::~Stock() { delete [] company; } // other methods void Stock::buy(int shares, double price) { if (shares < 0) { std::cerr << "Number of shares purchased can't be negative. " << "Transaction is aborted.\n"; } else { this->shares += shares; share_val = price; set_tot(); } } void Stock::sell(int shares, double price) { using std::cerr; if (shares < 0) { cerr << "Number of shares sold can't be negative. " << "Transaction is aborted.\n"; } else if (shares > this->shares) { cerr << "You can't sell more than you have! " << "Transaction is aborted.\n"; } else { this->shares -= shares; share_val = price; set_tot(); } } void Stock::update(double price) { share_val = price; set_tot(); } const Stock & Stock::topval(const Stock & stock) const { if (stock.total_val > total_val) return stock; else return *this; } // overloaded friend operators // simple output method ostream & operator<<(ostream & os, const Stock & stock) { using std::cout; using std::endl; os << "Company: " << stock.get_company() << " Shares: " << stock.get_shares() << endl << " Share Price: $" << stock.get_share_val() << " Total Worth: $" << stock.get_total_val() << endl; return os; } // Memory pool methods // Override for new operator // Stock's default constructor implicitly called here void* Stock::operator new (size_t size) { cout << "Allocate memory size to pool: " << size << endl; void *p = allocate_from_pool(size); return p; } // Override for delete operator // Stock's destructor implicitly called at this point void Stock::operator delete (void *p) { // return memory to pool cout << "return memory to pool: " << p << endl; release(p); } // memory allocation for a Stock object void* Stock::allocate_from_pool(size_t size) { // CODE THIS ROUTINE } // release memory for an object from pool void Stock::release (void *p) { // CODE THIS ROUTINE } // release memory for entire pool void Stock::release_all() { // CODE THIS ROUTINE }