//----------------------------------------------------------------- // // pointers-and-dynamic-memory.cpp // // Illustrates the the use of pointers and dynamic memory to build // a simple stack datastructure. // // A much less sophisticated stack than in dynamic-stack.cpp // // written by: Simon Parsons // modified : 15th March 2010 // //----------------------------------------------------------------- #include #include using namespace std; // Since this is meant to be a simple example, we will go against the // usual way of doing things in C++ and make the basic element of our // dynamic data structure absed on a struct. // // This means its memebrs are public by default, but we'll declare them // as public anyway. // // There are two members, an integer (the thing we store in the element) // and a pointer to the same kind of element. struct dataElement { public: int data; dataElement* dptr; }; int main() { // We start with a pointer --- this is what we use to keep track of // our dynamic datastructure dataElement* basePtr; // Create a dataelement and use the pointer to keep hold of it: basePtr = new dataElement; // Now set the integer part of the element. There are two ways to do // this: (*basePtr).data = 3; basePtr->data = 4; // We can visualise what we have like this: // // +---+ // basePtr --> | 4 | // +---+ // | | // +---+ // // The empty part of the data element is the pointer which we didn't // use yet. // We can access the top of the stack: cout << "The top data element contains: " << basePtr->data << endl; // Now let's add another data element. We need a pointer to keep track // of this new element, and we'll set its value dataElement* tmpPtr; tmpPtr = new dataElement; tmpPtr->data = 1; // Since we are building a stack, we want to "push" this element onto // the stack. That means we want a situation that looks (roughly) like this: // // // // +---+ +---+ // basePtr --> | 1 | | 4 | // +---+ +---+ // | *-|---> | | // +---+ +---+ // // so that basePtr gives us the most recent element to be added to the stack // and that element tells us where the next element is. // We do this like so: tmpPtr->dptr = basePtr; // make the new stack element point to what was // the top of the stack; basePtr = tmpPtr; // Set the new top of the stack; // Again we can access the top of the stack: cout << "The top data element contains: " << basePtr->data << endl; // So far we have needed one pointer for each data element, but we // can now add as many elements as we like without needing any new // pointers. In fact, we can just reuse lines of code we used before // (there's a function that needs to be written :-) tmpPtr = new dataElement; tmpPtr->data = 6; // A new value! tmpPtr->dptr = basePtr; basePtr = tmpPtr; // And we have: // // +---+ +---+ +---+ // basePtr --> | 6 | | 1 | | 4 | // +---+ +---+ +---+ // | *-|---> | *-|---> | | // +---+ +---+ +---+ // Again we can access the top of the stack: cout << "The top data element contains: " << basePtr->data << endl; // So that is pushing data onto the stack. Now let's look at popping // data off the stack. tmpPtr = basePtr; // Keep hold of the top element basePtr = basePtr->dptr; // Make basePtr point to the second element delete tmpPtr; // Delete the top element // This takes us back to here: // // +---+ +---+ // basePtr --> | 1 | | 4 | // +---+ +---+ // | *-|---> | | // +---+ +---+ // Now if we print the top of the stack: cout << "The top data element contains: " << basePtr->data << endl; // And so on. }