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», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.

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

Интервал:

Закладка:

Сделать

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

struct Sentinel {

~Sentinel() {

if (nptrs > 0) {

printf("Leaked memory at:\n");

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

printf("\t%p (file: %s, line %ld)\n",

memMap[i].ptr, memMap[i].file, memMap[i].line);

}

else

printf("No user memory leaks!\n");

}

};

// Static dummy object

Sentinel s;

} // End anonymous namespace

// Overload scalar new

void* operator new(size_t siz, const char* file,

long line) {

void* p = malloc(siz);

if (activeFlag) {

if (nptrs == MAXPTRS) {

printf("memory map too small (increase MAXPTRS)\n");

exit(1);

}

memMap[nptrs].ptr = p;

memMap[nptrs].file = file;

memMap[nptrs].line = line;

++nptrs;

}

if (traceFlag) {

printf("Allocated %u bytes at address %p ", siz, p);

printf("(file: %s, line: %ld)\n", file, line);

}

return p;

}

// Overload array new

void* operator new[](size_t siz, const char* file,

long line) {

return operator new(siz, file, line);

}

// Override scalar delete

void operator delete(void* p) {

if (findPtr(p) >= 0) {

free(p);

assert(nptrs > 0);

delPtr(p);

if (traceFlag)

printf("Deleted memory at address %p\n", p);

}

else if (!p && activeFlag)

printf("Attempt to delete unknown pointer: %p\n", p);

}

// Override array delete

void operator delete[](void* p) {

operator delete(p);

} ///:~

The Boolean flags traceFlagand activeFlagare global, so they can be modified in your code by the macros TRACE_ON( ), TRACE_OFF( ), MEM_ON( ), and MEM_OFF( ). In general, enclose all the code in your main( )within a MEM_ON( )- MEM_OFF( )pair so that memory is always tracked. Tracing, which echoes the activity of the replacement functions for operator new( )and operator delete( ), is on by default, but you can turn it off with TRACE_OFF( ). In any case, the final results are always printed (see the test runs later in this chapter).

The MemCheckfacility tracks memory by keeping all addresses allocated by operator new( )in an array of Infostructures, which also holds the file name and line number where the call to newoccurred. As much information as possible is kept inside the anonymous namespace so as not to collide with any names you might have placed in the global namespace. The Sentinelclass exists solely to have a static object’s destructor called as the program shuts down. This destructor inspects memMapto see if any pointers are waiting to be deleted (in which case you have a memory leak) .

Our operator new( )uses malloc( )to get memory, and then adds the pointer and its associated file information to memMap. The operator delete( )function undoes all that work by calling free( )and decrementing nptrs, but first it checks to see if the pointer in question is in the map in the first place. If it isn’t, either you’re trying to delete an address that isn’t on the free store, or you’re trying to delete one that’s already been deleted and therefore previously removed from the map. The activeFlagvariable is important here because we don’t want to process any deallocations from any system shutdown activity. By calling MEM_OFF( )at the end of your code, activeFlagwill be set to false, and such subsequent calls to deletewill be ignored. (Of course, that’s bad in a real program, but as we said earlier, our purpose here is to find your leaks; we’re not debugging the library.) For simplicity, we forward all work for array newand deleteto their scalar counterparts .

The following is a simple test using the MemCheckfacility.

//: C02:MemTest.cpp

//{L} MemCheck

// Test of MemCheck system

#include

#include

#include

#include "MemCheck.h" // Must appear last!

using namespace std;

class Foo {

char* s;

public:

Foo(const char*s ) {

this->s = new char[strlen(s) + 1];

strcpy(this->s, s);

}

~Foo() {

delete [] s;

}

};

int main() {

MEM_ON();

cout << "hello\n";

int* p = new int;

delete p;

int* q = new int[3];

delete [] q;

int* r;

delete r;

vector v;

v.push_back(1);

Foo s("goodbye");

MEM_OFF();

} ///:~

This example verifies that you can use MemCheckin the presence of streams, standard containers, and classes that allocate memory in constructors. The pointers pand qare allocated and deallocated without any problem, but ris not a valid heap pointer, so the output indicates the error as an attempt to delete an unknown pointer .

hello

Allocated 4 bytes at address 0xa010778 (file: memtest.cpp, line: 25)

Deleted memory at address 0xa010778

Allocated 12 bytes at address 0xa010778 (file: memtest.cpp, line: 27)

Deleted memory at address 0xa010778

Attempt to delete unknown pointer: 0x1

Allocated 8 bytes at address 0xa0108c0 (file: memtest.cpp, line: 14)

Deleted memory at address 0xa0108c0

No user memory leaks!

Because of the call to MEM_OFF( ), no subsequent calls to operator delete( )by vectoror ostreamare processed. You still might get some calls to deletefrom reallocations performed by the containers .

If you call TRACE_OFF( )at the beginning of the program, the output is as follows:

hello

Attempt to delete unknown pointer: 0x1

No user memory leaks! .

Summary

Much of the headache of software engineering can be avoided by being deliberate about what you’re doing. You’ve probably been using mental assertions as you’ve crafted your loops and functions anyway, even if you haven’t routinely used the assert( )macro. If you’ll use assert( ), you’ll find logic errors sooner and end up with more readable code as well. Remember to only use assertions for invariants, though, and not for runtime error handling.

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

Интервал:

Закладка:

Сделать

Похожие книги на «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