Bruce Eckel - Thinking In C++. Volume 2 - Practical Programming

Здесь есть возможность читать онлайн «Bruce Eckel - Thinking In C++. Volume 2 - Practical Programming» весь текст электронной книги совершенно бесплатно (целиком полную версию без сокращений). В некоторых случаях можно слушать аудио, скачать через торрент в формате fb2 и присутствует краткое содержание. Год выпуска: 2003, ISBN: 2003, Издательство: Prentice Hall, Жанр: Программирование, на английском языке. Описание произведения, (предисловие) а так же отзывы посетителей доступны на портале библиотеки ЛибКат.

Thinking In C++. Volume 2: Practical Programming: краткое содержание, описание и аннотация

Предлагаем к чтению аннотацию, описание, краткое содержание или предисловие (зависит от того, что написал сам автор книги «Thinking In C++. Volume 2: Practical Programming»). Если вы не нашли необходимую информацию о книге — напишите в комментариях, мы постараемся отыскать её.

Best selling author Bruce Eckel has joined forces with Chuck Allison to write
, the sequel to the highly received and best selling
. Eckel is the master of teaching professional programmers how to quickly learn cutting edge topics in C++ that are glossed over in other C++ books. In
, the authors cover the finer points of exception handling, defensive programming and string and stream processing that every C++ programmer needs to know. Special attention is given to generic programming where the authors reveal little known techniques for effectively using the Standard Template Library. In addition, Eckel and Allison demonstrate how to apply RTTI, design patterns and concurrent programming techniques to improve the quality of industrial strength C++ applications. This book is targeted at programmers of all levels of experience who want to master C++.

Thinking In C++. Volume 2: Practical Programming — читать онлайн бесплатно полную книгу (весь текст) целиком

Ниже представлен текст книги, разбитый по страницам. Система сохранения места последней прочитанной страницы, позволяет с удобством читать онлайн бесплатно книгу «Thinking In C++. Volume 2: Practical Programming», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.

Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Debugging techniques

The best debugging habit to get into is to use assertions as explained in the beginning of this chapter; by doing so you’ll be more likely to find logic errors before they cause real trouble. This section contains some other tips and techniques that might help during debugging .

Trace macros

Sometimes it’s helpful to print the code of each statement as it is executed, either to coutor to a trace file. Here’s a preprocessor macro to accomplish this: .

#define TRACE(ARG) cout << #ARG << endl; ARG

Now you can go through and surround the statements you trace with this macro. Of course, it can introduce problems. For example, if you take the statement: .

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

cout << i << endl;

and put both lines inside TRACE( )macros, you get this:

TRACE(for(int i = 0; i < 100; i++))

TRACE( cout << i << endl;)

which expands to this:

cout << "for(int i = 0; i < 100; i++)" << endl;

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

cout << "cout << i << endl;" << endl;

cout << i << endl;

which isn’t exactly what you want. Thus, you must use this technique carefully .

The following is a variation on the TRACE( )macro:

#define D(a) cout << #a "=[" << a << "]" << '\n';

If you want to display an expression, you simply put it inside a call to D( ).The expression is displayed, followed by its value (assuming there’s an overloaded operator <<for the result type). For example, you can say D(a + b). Thus, you can use this macro any time you want to test an intermediate value to make sure things are okay .

Of course, these two macros are actually just the two most fundamental things you do with a debugger: trace through the code execution and display values. A good debugger is an excellent productivity tool, but sometimes debuggers are not available, or it’s not convenient to use them. These techniques always work, regardless of the situation .

Trace file

DISCLAIMER: This section and the next contain code which is officially unsanctioned by the C++ standard. In particular, we redefine coutand newvia macros, which can cause surprising results if you’re not careful. Our examples work on all the compilers we use, however, and provide useful information. This is the only place in this book where we will depart from the sanctity of standard-compliant coding practice. Use at your own risk!

The following code allows you to easily create a trace file and send all the output that would normally go to coutinto the file. All you have to do is #defineTRACEON and include the header file (of course, it’s fairly easy just to write the two key lines right into your file): .

//: C03:Trace.h

// Creating a trace file

#ifndef TRACE_H

#define TRACE_H

#include

#ifdef TRACEON

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

} ///:~

Finding memory leaks

The following straightforward debugging techniques are explained Volume 1.

1. For array bounds checking, use the Arraytemplate in C16:Array3.cppof 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 .

Tracking new/delete and malloc/free

Common problems with memory allocation include mistakenly calling deletefor 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] Our key technical reviewer, Pete Becker of Dinkumware. Ltd., brought to our attention that it is illegal to use macros to replace C++ keywords. His take on this technique was as follows: “"This is a dirty trick. Dirty tricks are sometimes necessary to figure out why code isn't working, so you may want to keep this in your toolbox, but don't ship any code with it." Caveat programmer :-).

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.objfile into your application, so that all the calls to newand deleteare 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 newstore information about the file and line where they were called. This is accomplished by using the placement syntax for operator new. [27] Thanks to Reg Charney of the C++ Standards Committee for suggesting this trick. 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 newis 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 #includedirectives). 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 newin MemCheck.hwould usurp all instances of the newoperator 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 .

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Похожие книги на «Thinking In C++. Volume 2: Practical Programming»

Представляем Вашему вниманию похожие книги на «Thinking In C++. Volume 2: Practical Programming» списком для выбора. Мы отобрали схожую по названию и смыслу литературу в надежде предоставить читателям больше вариантов отыскать новые, интересные, ещё непрочитанные произведения.


Отзывы о книге «Thinking In C++. Volume 2: Practical Programming»

Обсуждение, отзывы о книге «Thinking In C++. Volume 2: Practical Programming» и просто собственные мнения читателей. Оставьте ваши комментарии, напишите, что Вы думаете о произведении, его смысле или главных героях. Укажите что конкретно понравилось, а что нет, и почему Вы так считаете.

x