Click Here!
home account info subscribe login search FAQ/help site map contact us


 
Brief Full
 Advanced
      Search
 Search Tips
[an error occurred while processing this directive]
Previous Table of Contents Next


4.  Save MAILSERVER.CPP. Create a new file with the name MAIN.CPP and type the following code into it:
// demonstarting how to
// avoid recurrent memory
// reallocations of vector

#include <iostream>
#include “mailserver.h”

using namespace std;

void main()
{
 MailServer server;
 vector <message> vm;  //emails transmitted from the server are
		       //stored here

 if (server.RushHour())
  vm.reserve(5000); //make room for at least 5000 more messages
		    //without reallocation
 while (server.MoreMessages())
 {

   static int count =0;   // control how many times this loop
			  // executes
   vm.push_back( server.GetNewMsg() ); //insert a new email into                                        //vm
   count++;
   if (count > 5000)
     break; //loop exited after 5000 iterations
 }//while

}// end main
5.  Save MAIN.CPP and compile your project.
If your compiler complains about the following #include statement in CALLCHAIN.H or CALLCHAIN.CPP:
#include <vector>

comment out (or remove) the using directive just below the #include statement and change them to read:
#include <vector.h>
6.  Compile and link the project.
7.  Run main.exe.

How It Works

Let’s look at MAILSERVER.H. The first source line includes STL <vector> definitions. Next, a struct named message is declared that represents a typical email message. The class MailServer is also declared. This class represents a rudimentary mail server. It has four public member functions and no data members, constructors, or destructors.

For a more detailed description of each member function, let’s look at MAILSERVER.CPP. The first source line includes the declaration of class MailServer.

#include “mailserver.h”

The following lines define MailServer’s member functions. The member function RushHour returns true if the current time falls between 9:00 and 17:00. To simplify things, use a stub that always returns true to avoid time calculations that are impertinent to this discussion. The reason a local variable is used and initialized (rather than simply returning a literal true) is to enable you to change its value from a debugger and test the resulting effect. RushHour is declared const because it does not change its object’s state.

bool MailServer::RushHour() const
{
 bool rush = true;
 return rush;
}

MoreMessages is the second member function of MailServer. Again, a stub is used here that always returns true. MoreMessages checks whether new messages are coming. In real-world conditions, it would probe the shared memory or a communication port.

bool MailServer::MoreMessages() const
{
  bool more = true;
  return more;
}

In case more messages are on the way, the member function GetNewMessage is invoked. In this case, hold a static instance of a message struct, and return it by reference. Static variables are instantiated and initialized only once during a program’s execution, so they are more efficient than local variables that are instantiated anew every time. The returned message is stored in the container, as you will immediately see in MAIN.CPP.

message& MailServer::GetNewMsg() const
{
  static message msg;
  return msg;
}

Let’s look at MAIN.CPP. The first source line inside main() instantiates server, an object of type MailServer.

MailServer server;

In the following line, a vector object named vm is instantiated, whose type is vector<message>. The container vm will store the email messages coming from the server object.

vector <message> vm;

The next if statement queries server whether the current time is considered rush hour. If it is, vm must be prepared to handle the traffic load by reserving enough room for at least 5000 more messages.

if (server.RushHour())
   vm.reserve(5000);

Remember that vector::reserve takes the number of objects as an argument, not the number of bytes. Thus, vm has to reserve memory in the size of 5000 * sizeof(message) bytes, which is nearly 5MB.

The while condition is, in fact, an infinite loop because it tests a condition that is always true (as you might recall, MoreMessages always returns true). Exit from the loop by using a static int, which is incremented with every iteration, until the loop has executed 5000 times.

while (server.MoreMessages())
{
  static int count =0;

The message is retrieved from the server, and stored in vm. For that purpose, invoke push_back with the message returned from GetNewMsg() as an argument. Next, increment count, the loop counter, and test whether the loop has already executed 5000 times. If it has, break from the loop. Otherwise, the loop executes once more.

   vm.push_back( server.GetNewMsg() );
   count++;
   if (count > 5000)
     break;
 }//while
}// end main

Comments

In this example, you have to adjust a vector’s memory according to need. When you have to use a vector that is always required to hold large amounts of memory—for example, a vector that holds all of the records of a large database table—you can use a different technique.

Up until now, you have instantiated vectors with their default constructor. However, vector has another constructor that takes as an argument the initial number of elements for which storage has to be reserved. In other words, you could have instantiated vm like this:

vector <message> vm(5000); // prepare enough room for 5000 messages initially

But that would be a waste of the system’s resources if it wasn’t working during rush hours.

You are probably wondering why you should bother so much about avoiding reallocations when a vector can do the necessary bookkeeping automatically. The motive in this How-To was to optimize performance and to ensure the highest responsiveness. Nevertheless, there is another reason for avoiding reallocations, which is discussed in length in How-To 7.6.


Previous Table of Contents Next


Products |  Contact Us |  About Us |  Privacy  |  Ad Info  |  Home

Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written permision of EarthWeb is prohibited.