Читаем Thinking In C++. Volume 2: Practical Programming полностью

ofstream TRACEFILE__("TRACE.OUT");

#define cout TRACEFILE__

#endif

#endif // TRACE_H ///:~

Here’s a simple test of the previous file:

//: C03:Tracetst.cpp

// Test of trace.h

#include "../require.h"

#include

#include

using namespace std;

#define TRACEON

#include "Trace.h"

int main() {

  ifstream f("Tracetst.cpp");

  assure(f, "Tracetst.cpp");

  cout << f.rdbuf(); // Dumps file contents to file

} ///:~

<p>Finding memory leaks</p>

The following straightforward debugging techniques are explained Volume 1.

1.       For array bounds checking, use the Array template in C16:Array3.cpp of Volume 1 for all arrays. You can turn off the checking and increase efficiency when you’re ready to ship. (This doesn’t deal with the case of taking a pointer to an array, though—perhaps that could be made into a template somehow as well).

2.      Check for non-virtual destructors in base classes.

<p>Tracking new/delete and malloc/free</p>

Common problems with memory allocation include mistakenly calling delete for memory not on the free store, deleting the free store more than once, and, most often, forgetting to delete such a pointer at all. This section discusses a system that can help you track down these kinds of problems.

As an additional disclaimer beyond that of the preceding section: because of the way we overload new, the following technique may not work on all platforms, and will only work for programs that do not call the function operator new( ) explicitly. We have been quite careful in this book to only present code that fully conforms to the C++ standard, but in this one instance we’re making an exception for the following reasons:

             1.             Even though it’s technically illegal, it works on many compilers.[26]

             2.             We illustrate some useful thinking along the way.

To use the memory checking system, you simply include the header file MemCheck.h, link the MemCheck.obj file into your application, so that all the calls to new and delete are intercepted, and call the macro MEM_ON( ) (explained later in this section) to initiate memory tracing. A trace of all allocations and deallocations is printed to the standard output (via stdout). When you use this system, all calls to new store information about the file and line where they were called. This is accomplished by using the placement syntax for operator new.[27] Although you typically use the placement syntax when you need to place objects at a specific point in memory, it also allows you to create an operator new( ) with any number of arguments. This is used to advantage in the following example to store the results of the __FILE__ and __LINE__ macros whenever new is called:.

//: C02:MemCheck.h

#ifndef MEMCHECK_H

#define MEMCHECK_H

#include   // for size_t

// Hijack the new operator (both scalar and array versions)

void* operator new(std::size_t, const char*, long);

void* operator new[](std::size_t, const char*, long);

#define new new (__FILE__, __LINE__)

extern bool traceFlag;

#define TRACE_ON() traceFlag = true

#define TRACE_OFF() traceFlag = false

extern bool activeFlag;

#define MEM_ON() activeFlag = true

#define MEM_OFF() activeFlag = false

#endif

///:~

It is important that you include this file in any source file in which you want to track free store activity, but include it last (after your other #include directives). Most headers in the standard library are templates, and since most compilers use the inclusion model of template compilation (meaning all source code is in the headers), the macro that replaces new in MemCheck.h would usurp all instances of the new operator in the library source code (and would likely result in compile errors). Besides, you are only interested in tracking your own memory errors, not the library’s.

In the following file, which contains the memory tracking implementation, everything is done with C standard I/O rather than with C++ iostreams. It shouldn’t make a difference, really, since we’re not interfering with iostreams’ use of the free store, but it’s safer to not take a chance. (Besides, we tried it. Some compilers complained, but all compilers were happy with the version.).

//: C02:MemCheck.cpp {O}

#include

#include

#include

using namespace std;

#undef new

// Global flags set by macros in MemCheck.h

bool traceFlag = true;

bool activeFlag = false;

namespace {

// Memory map entry type

struct Info {

  void* ptr;

  const char* file;

  long line;

};

// Memory map data

const size_t MAXPTRS = 10000u;

Info memMap[MAXPTRS];

size_t nptrs = 0;

// Searches the map for an address

int findPtr(void* p) {

  for (int i = 0; i < nptrs; ++i)

    if (memMap[i].ptr == p)

      return i;

  return -1;

}

void delPtr(void* p) {

  int pos = findPtr(p);

  assert(p >= 0);

  // Remove pointer from map

  for (size_t i = pos; i < nptrs-1; ++i)

    memMap[i] = memMap[i+1];

  --nptrs;

}

// Dummy type for static destructor

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных