×åòèðèêðàòíîòî èçïúëíåíèå íà exhaustFreeStore() Ñ àðãóìåíòè,
êîèòî èìàò ðàçëè÷åí ðàçìåð äàâà ñëåäíèÿ ðåçóëòàò
Free Store
Exhaused
ckunk 1000000 depth 4
Free Store Exhaused
ckunk 100000
depth 22
Free Store Exhaused
ckunk 10000 depth 209
Free Store
Exhaused
ckunk 1000 depth 2072
Åäíà îò Ñ++ áèáëèîòåêèòå ïðåäëàãà
èçâåñòíà ïîìîù, êàòî ïîääúðæà èíôîðìàöèÿ çà ñâîáîäíàòà ïàìåò. Ìàíèïóëàòîðúò,
îáðàáîòâàù èçêëþ÷åíèÿòà _new_handler ñå ðàçãëåæäà â Ðàçäåë 5.4 ïî-íàòàòúê â òàçè
ãëàâà.
Ïðîãðàìèñòúò ñúùî ìîæå äà ïîñòàâè îáåêò, ðàçïîëîæåí â ñâîáîäíàòà
ïàìåò íà îïðåäåëåí àäðåñ. Ôîðìàòà íà òàêîâà èçâèêâàíå íà îïåðàòîðà new èìà
âèäà
new (place_address) type-specifier
êúäåòî place_address
òðÿáâà äà áúäå óêàçàòåë. Çà äà èçïîëçâàòå îïåðàòîðà new ïî òîçè íà÷èí òðÿáâà
âêëþ÷èòå çàãëàâíèÿ ôàéë new.h. Ïî òîçè íà÷èí ïðîãðàìèñòúò ìîæå äà ïðåðàçïðåäåëÿ
ïàìåòòà, êîÿòî â åäèí ïî-íàòàòúøåí ìîìåíò ùå ñúäúðæà îáåêòè, îïðåäåëåíè ÷ðåç
òàçè ôîðìà íà îïåðàòîðà new. Íàïðèìåð,
#include
<stream.h>
#include <new.h>
const Chunk = 16;
class
Foo { public
int val;
Foo() { val = 0; }
};// preallocate memory, but
no Foo objects
char *buf = new char[ sizeof( Foo ) * Chunk ];
main()
{
// construct Chunk Foo objects for buf
Foo *pb = new (buf) Foo[ Chunk
];
// check that objects were plased in buf
if ( (char*)pb == buf
)
cout << "Operator new worked! pb "<< pb << " buf
"
<< (void* )buf << "n";
}
Êîãàòî òàçè ïðîãðàìà áúäå
êîìïèëèðàíà è èçïúëíåíà ùå ïîëó÷èì ñëåäíèòå ðåçóëòàòè
Operator new
worked!
pb 0x234cc
buf 0x234cc
Âúçìîæíî å äà ñå ïîÿâè èçâåñòíî
îáúðêâàíå îòíîñíî òàçè ïðîãðàìà. Òî å ñâúðçàíî ñ èçïðàùàíåòî íà buf êúì void*.
Òîâà å íåîáõîäèìî, ïîíåæå êîãàòî êúì îïåðàòîðà çà èçõîä ñå èçïðàùà îïåðàíä char*
ñå îòïå÷àòâà “null terminated string”, ò.å. íèçà, êîéòî å àäðåñèðàí. ×ðåç
èçïðàùàíåòî íà buf êúì void* îïåðàòîðúò çà èçõîä çíàå, ÷å òðÿáâà äà îòïå÷àòà
àäðåñíàòà ñòîéíîñò íà buf. Òîâà ñå äúëæè íà ôàêòà, ÷å îïåðàòîðúò çà èçõîä ñå
ïðåçàðåæäà òàêà, ÷å äà èçïîëçâàò äâà ðàçëè÷íè óêàçàòåëíè òèïîâå íà àðãóìåíòè
char* è void*. Ïðåçàðåäèìèòå ôóíêöèè ñå ðàçãëåæäàò â åäèí îò ïîäðàçäåëèòå íà
òàçè ãëàâà. Âúïðåêè, ÷å òîçè òèï íà îïåðàòîðà new ñå èçïîëçâà ãëàâíî ñ òèïîâåòå
class, òîé ìîæå äà ñå èçïîëçâàò è çà âãðàäåíèòå òèïîâå äàííè.
Íàïðèìåð,
#include <new.h>
int *pi = new
int;
main(){
int *pi2 = new (pi) int;
}
5.2. Åäèí
ïðèìåð çà ñâúðçàí ñïèñúê
 òîçè ðàçäåë ñå ðåàëèçèðà åäèí åëåìåíòàðåí
êëàñ ñïèñúê îò öåëè ÷èñëà çà äà áúäå èëþñòðèðàíà êàêòî ðàáîòàòà ñ óêàçàòåëè,
òàêà è èçïîëçâàíåòî íà îïåðàòîðèòå new è delete. Êàòî ìèíèìóì IntList òðÿáâà äà
ïîääúðæà äâå ñòîéíîñòè - öÿëàòà ñòîéíîñò íà åëåìåíòà íà ñïèñúêà è àäðåñà íà
ñëåäâàùèÿ åëåìåíò íà ñïèñúêà. Òîâà ìîæå äà ñå ïðåäñòàâè ïî ñëåäíèÿ
íà÷èí
int val;
ListItem *next;
Åäèí ñïèñúê ïðåäñòàâëÿâà
ïîñëåäîâàòåëíîñò îò åëåìåíòè. Âñåêè åëåìåíò ñúäúðæà ñòîéíîñò è óêàçàòåë, ìîæå è
null, êúì ñëåäâàùèÿ åëåìåíò íà ñïèñúêà. Ñïèñúêúò ìîæå äà áúäå è ïðàçåí; ò.å. äà
áúäå ñïèñúê áåç åëåìåíòè
IntList i1; // the empty list
Ñïèñúêúò
ìîæå äà íàðàñòâà ÷ðåç äîáàâÿíå íà åëåìåíòè. Òåçè åëåìåíòè ìîãàò äà áúäàò
âìúêâàíè â íà÷àëîòî íà ñïèñúêà
i1.insert( someValue );
èëè
äîáàâÿíè êúì êðàÿ ìó
i1.append( someValue );
Ñïèñúêúò ìîæå äà áúäå
íàìàëÿâàí ÷ðåç îòñòðàíÿâàíå íà åëåìåíòè (ïðåäïîëàãà ñå, ÷å òîé íå å
ïðàçåí)
i1.remove( someValue );
Ïîòðåáèòåëÿò òðÿáâà äà áúäå â
ñúñòîÿíèå äà ïîêàçâà åëåìåíòèòå íà íà ñïèñúêà
i1.display();
Åòî
åäíà ïúðâà ïðîãðàìà, êîÿòî áèõìå æåëàëè äà íàïèøåì êàòî èçïîëçâàìå êëàñà
IntList.
#include "IntList.h"
const SZ = 12;
main()
{
IntList i1;
i1.display();
for ( int i = 0; i < SZ; ++i
)
i1.insert( i );
i1.display();
IntList i12;
for ( i = 0; i <SZ;
++i ) i12.append( i );
i12.display();
return 0;
}
Êîãàòî òàçè
ïðîãðàìà áúäå êîìïèëèðàíà è èçïúëíåíà ñå ïîëó÷àâà ñëåäíèÿ ðåçóëòàò
(
empty )( 11 10 9 8 7 6 5 4 3 2 1 0 )( 0 1 2 3 4 5 6 7 8 9 10 11 )
Ïúðâàòà
ñòúïêà çà ðåàëèçàöèÿòà íà òàçè ïðîãðàìà å äåôèíèðàíåòî íà êëàñà IntList. Òîâà å
è ïúðâîòî ìÿñòî, êúäåòî ìîæåì äà ñãðåøèì. Íåïðàâèëåí çà ïðîåêòà èçáîð ùå áúäå äà
äåêëàðèðàìå êàêòî val, òàêà è next êàòî ÷ëåíîâå íà IntList.
Íàïðèìåð,
class IntList {
public IntList ( int = ??? );
//
...private
int val;
IntLIst *next;
};
Ïðè òîçè ïðîåêò âúçíèêâàò
íÿêîëêî ïðîáëåìà. Âñè÷êèòå òå ïðîèçòè÷àò îò îáúðêâàíåòî ìåæäó îáåêòà ñïèñúê è
åëåìåíòà íà ñïèñúêà. Íàïðèìåð, ïðè òîçè ïðîåêò íå ñå äîïóñêà íàëè÷èåòî íà ïðàçåí
ñïèñúê. Íå ñúùåñòâóâà íà÷èí çà ðàçãðàíè÷àâàíå íà ñïèñúêà, ñúäúðæàù åäèí åëåìåíò
îò ïðàçíèÿ ñïèñúê. Âúïðîñèòåëíèòå çíàöè, â ñèãíàòóðàòà íà êîíñòðóêòîðà íà
IntList ñà ïðåäíàçíà÷åíè äà ïîä÷åðòàÿò òîçè ïðîáëåì. Íÿìà ïîäðàçáèðàùà ñå
ñòîéíîñò çà èíèöèàëèçèðàíå íà val, ÷ðåç êîÿòî äà ñå îòáåëÿçâà, ÷å ñïèñúêúò å
ïðàçåí. Äðóãèòå ïðîáëåìè âúçíèêâàò îò òîâà, ÷å íå å îïðåäåëåí ñìèñúëà íà
insert() è remove() êîãàòî îáåêòúò îò òèï IntList ïðåäëàãà ñúùî è ïúðâèÿ åëåìåíò
íà ñïèñúêà.
 ïðåêòà íà IntList òðÿáâà äà áúäå íàïðàâåíî ðàçãðàíè÷àâàíå
ìåæäó åëåìåíòèòå íà ñïèñúêà è ñàìèÿ îáåêò ñïèñúê êàòî òàêúâ. Åäèí îò íà÷èíèòå äà
áúäå íàïðàâåíî òîâà å äà áúäå äåôèíèðàí êàêòî êëàñ IntList, òàêà è êëàñ IntItem.
Åòî äåôèíèöèÿòà íà IntItem
class IntList;
class intItem{
friend
class IntList;
private IntItem( int v=0 ) { val = v; next = 0 )
IntItem
*next;
int val;
};
IntItem ñå íàðè÷à êëàñ private (ëè÷åí). Ñàìî íà
IntList å ðàçðåøåíî äà ñúçäàâà è îáðàáîòâà IntItem îáåêòèòå. Òîâà å ñìèñúëà íà
äåêëàðàöèÿòà friend. Ðàçäåë 6.5 ðàçãëåæäà ïîäðîáíî òàçè äåêëàðàöèÿ. Ðàçäåë 6.1
îáÿñíÿâà ðàçëèêèòå ìåæäó äåêëàðàöèèòå private è public. IntList å ðåàëèçèðàí ïî
ñëåäíèÿ íà÷èí:
class IntItem;
class IntList {
public IntList(int
val) { list = new IntItem( val ); }
IntList() { list = 0; }//
...
private
IntItem *list;
};
Óïðàæíåíèå 5-1. Çàùî IntList ñå
íóæäàå îò äâà êîíñòðóêòîðà? Çàùî, íàïðèìåð, äà íå äåôèíèðàìå ïðîñòîIntList( val
= 0 );
Óïðàæíåíèå 5-2. Åäèí äîïúëíèòåëåí ÷ëåí äàííè íà IntList ìîæå äà áúäå
int len; // length of list, êîéòî äà ñúäúðæà áðîÿ íà åëåìåíòèòå íà ñïèñúêà.
Ðàçãëåäàéòå àðãóìåíòèòå çà è ïðîòèâ òàçè äåêëàðàöèÿ.
Ñëåäâàùàòà ñòúïêà ñå
ñúñòîè â ðåàëèçèðàíåòî íà ÷ëåí-ôóíêöèè, êîèòî ïîääúðæàò ïîòðåáèòåëñêèòå
îáðàáîòêè íà IntList îáåêòèòå. insert() ïîñòàâÿ äàäåí íîâ IntItem â íà÷àëîòî íà
ñïèñúêà. Òîâà ñå ðåàëèçèðà òàêà
IntList
insert( int val ) {
// add
to the front of the list
IntItem *pt = new IntItem( val );
pt->next =
list;
list = pt;
return val;
}
append() å ìàëêî ïî-ñëîæíà. Òÿ
òðÿáâà äà äîáàâÿ íîâ IntItem â êðàÿ íà ñïèñúêà. Åäíà ïîìîùíà ôóíêöèÿ, atEnd(),
âðúùà óêàçàòåë êúì ïîñëåäíèÿ åëåìåíò íà ñïèñúêà
IntItem
*IntList
atEnd(){ // return pointer to last item on list
IntItem *prv,
*pt;
for ( prv=pt=list; pt; prv=pt; pt=pt->next ); // null
statement
return prv;
}
append() òðÿáâà äà ïðîâåðÿâà ñïåöèàëíèÿ
ñëó÷àé íà ïðàçåí ñïèñúê. Ðåàëèçàöèÿòà èçãëåæäà ïî ñëåäíèÿ
íà÷èí
IntList
append( int val ) {
// add to the back of the
list
IntItem *pt = new IntItem( val );
if ( list == 0 ) list = pt;
else
(atEnd())->next = pt;
return val;
}