// ------------------------------- // // -------- Start of File -------- // // ------------------------------- // // ----------------------------------------------------------- // // C++ Source Code File Name: testprog.cpp // Compiler Used: MSVC, BCC32, GCC, HPUX aCC, SOLARIS CC // Produced By: DataReel Software Development Team // File Creation Date: 04/05/1996 // Date Last Modified: 06/17/2016 // Copyright (c) 2001-2024 DataReel Software Development // ----------------------------------------------------------- // // ------------- Program Description and Details ------------- // // ----------------------------------------------------------- // /* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Doubly linked list class test program. */ // ----------------------------------------------------------- // #include "gxdlcode.h" #if defined (__USE_ANSI_CPP__) // Use the ANSI Standard C++ library #include <iostream> using namespace std; // Use unqualified names for Standard C++ library #else // Use the old iostream library by default #include <iostream.h> #endif // __USE_ANSI_CPP__ #include <string.h> #include "gxlistb.h" #ifdef __MSVC_DEBUG__ #include "leaktest.h" #endif void PausePrg() { // Pause the program until enter is pressed cout << endl; cout << "Press Enter to continue..." << "\n"; cin.get(); } void ScrollForward(gxListB &list) { cout << "Walking through the list..." << "\n"; gxListNodeB *ptr = list.GetHead(); while(ptr) { int val = (int)ptr->data; cout << (char)val << ' '; ptr = ptr->next; } cout << "\n"; } void RewindList(gxListB &list) { cout << "Walking through the list in a backward direction..." << "\n"; gxListNodeB *ptr = list.GetTail(); // Walk through the list in a backward direction while(ptr) { int val = (int)ptr->data; cout << (char)val << ' '; ptr = ptr->prev; } cout << "\n"; } int main() { #ifdef __MSVC_DEBUG__ InitLeakTest(); #endif gxListB list; gxListNodeB *ptr; // Construct some list nodes cout << "Loading data elements into linked list..." << "\n"; gxListNodeB *na = new gxListNodeB; gxListNodeB *nb = new gxListNodeB; gxListNodeB *nc = new gxListNodeB; gxListNodeB *nd = new gxListNodeB; gxListNodeB *n1 = new gxListNodeB; gxListNodeB *n2 = new gxListNodeB; gxListNodeB *n3 = new gxListNodeB; gxListNodeB *n4 = new gxListNodeB; // Statically allocated list data const unsigned num_blocks = 9; char buf[num_blocks]; unsigned i; // Load some values into the buffer starting with ASCII character 'A' for(i = 0; i < num_blocks; i++) buf[i] = (char)(65+i); na->data = (void *)buf[0]; nb->data = (void *)buf[1]; nc->data = (void *)buf[2]; nd->data = (void *)buf[3]; // Load some list elements list.InsertAfter(list.GetHead(), na); list.InsertAfter(na, nb); list.InsertAfter(nb, nc); list.InsertAfter(nc, nd); n1->data = (void *)buf[4]; n2->data = (void *)buf[5]; n3->data = (void *)buf[6]; n4->data = (void *)buf[7]; // Testing insert functions list.InsertBefore(na, n1); list.InsertBefore(nc, n2); list.InsertAfter(nb, n3); list.InsertAfter(nd, n4); // Reordering the list list.MoveToBack(na); list.MoveAfter(na, nc); list.MoveBefore(nc, nb); list.MoveAfter(nc, nd); list.MoveAfter(nd, n2); list.MoveBefore(n2, n1); list.MoveAfter(n2, n3); list.MoveAfter(n3, n4); ScrollForward(list); RewindList(list); PausePrg(); cout << "Adding another item to the list..." << "\n"; ptr = list.Add((void *)buf[8]); ScrollForward(list); PausePrg(); cout << "Moving list item to the front of the list" << "\n"; list.MoveToFront(ptr); ScrollForward(list); cout << "Moving item to the back of the list..." << "\n"; list.MoveToBack(ptr); ScrollForward(list); PausePrg(); cout << "Removing the head of the list..." << "\n"; ptr = list.GetHead(); list.Remove(ptr); ScrollForward(list); cout << "Removing the tail of the list..." << "\n"; ptr = list.GetTail(); list.Remove(ptr); ScrollForward(list); // NOTE: A gxListB::ClearList() call is used here to free the memory // allocated for the node since the node data was statically allocated. list.ClearList(); PausePrg(); cout << "Testing for memory leaks..." << "\n"; const char *test_str = "The quick brown fox jumps over the lazy dog"; unsigned len = strlen(test_str); const unsigned num_to_allocate = 10 * 100; // 1000 * 1000; const unsigned mem_bufs = (sizeof(gxListNodeB) + len) * num_to_allocate; cout << "Allocating " << mem_bufs << " bytes..." << "\n"; unsigned count1 = 0; unsigned count2 = 0; for(i = 0; i < num_to_allocate; i++) { char *sbuf = new char[len+1]; // Allocate memory for the string count1 += sizeof(sbuf); if(!sbuf) { cout << "Memory allocation error at " << (count1+count2) << " bytes" << "\n"; break; } memmove(sbuf, test_str, len); sbuf[len] = 0; // Null terminate the string count2 += sizeof(gxListNodeB); if(!list.Add((void *)sbuf)) { cout << "Memory allocation error at " << (count1+count2) << " bytes" << "\n"; break; } } cout << "Done" << "\n"; PausePrg(); cout << "Releasing memory allocated back to the heap..." << "\n"; // NOTE: A gxListB::DestroyList() call will free the memory allocated for // both the node and its data. list.DestroyList(); PausePrg(); cout << "Exiting..." << "\n"; cout << "\n"; return 0; } // ----------------------------------------------------------- // // ------------------------------- // // --------- End of File --------- // // ------------------------------- //