Mám otázku ohľadom ukazovateľa.
V knihe je napísaný takýto kód:
Kód:
Node * temp;
while (zaciatok != NULL)
{
temp = zaciatok;
zaciatok = zaciatok->dalsi;
delete temp;
}
ako je možné, že tam je delete?
Node je štruktúra, v knihe sa píše o dynamickej pamäti že ak ukazovateľovi, ktorému nepriradím novú pamäť (teda nepoužijem operátor
new), tak nemám použiť
delete, ale naopak pri priraďovaní pamäti
delete je potrebné použiť.
Celý kód beží bez nejakej chyby alebo hlásenia upozornenia v kompilátore.
Ďalšia otázka je ohľadom ukazovateľa a priradení hodnoty 0, alebo NULL.
ak spravím toto:
Kód:
Node * zaciatok;
zaciatok = NULL;
tak ak tomu správne chápem, ukazovateľ na štruktúru
zaciatok, bude ukazovať na nič? Teda nebude mať pridelenú pamäť?
Ak to pomôže dávam sem celý kód, je to z knihy prepísané. Ide o simuláciu fronty, navyše mám pocit, že tam je ďalšia chyba a to taká, kde sa priraďuje pamäť na štruktúru
add ale potom sa nevymaže - nepoužije sa operátor
deleteEdit: Ešte ma taká vec napadla, že v podstate ukazovateľ na štruktúru add vytvoril / vyhradil miesto pre pamäť, ale v kóde si tú pamäť prehadzovali až k tomu ukazovateľovi temp a ten ju vymazal. Čiže všetko je potom v poriadku? Správne tomu chápem? Čiže ak alokujem pamäť pomocou jedného ukazovateľa, je jedno či tú pamäť vymaže iným ukazovateľom?
Kód:
#ifndef QUE_H_
#define QUE_H_
class Zakaznik
{
private:
long prichod;
int casprocesu;
public:
Zakaznik() { prichod = casprocesu = 0; }
void set(long w);
long kedy() const { return prichod; }
int pcas() const { return casprocesu; }
};
typedef Zakaznik Item;
class Q
{
private:
// definicia platnosti v nutri triedy
struct Node { Item item; struct Node * dalsi; }; // Definicia struktury Node vo vnutri triedy
enum { Q_SIZE = 10 };
Node * zaciatok; // ukazatel na zaciatok fronty
Node * koniec; // ukazatel na koniec f.
int items; // aktualny pocet poloziek fronty
const int qsize; // maximalny pocet poloziek fronty
// preventivne definicie pre zamezenie verejneho kopirovania
Q(const Q & q) : qsize(0) {}
Q & operator=(const Q & q) { return *this; }
public:
Q(int qs = Q_SIZE); // vytvori frontu s limitom
~Q();
bool isempty() const;
bool isfull() const;
int qcount() const;
bool enq(const Item & item); // prida polozku na koniec
bool deq(Item & item); // odobere polozku zo zaciatku
};
#endif // !QUE_H_
Kód:
#include "que.h"
#include <cstdlib>
// metody triedy que
Q::Q(int qs) : qsize(qs){
zaciatok = koniec = NULL;
items = 0;
}
Q::~Q(){
Node * temp;
while (zaciatok != NULL){
temp = zaciatok; // ulozi adresu prvej polozky
zaciatok = zaciatok->dalsi; // nastavi ukazatel na dalsiu polozku
delete temp; // zrusi povodnu prvu polozku
}
}
bool Q::isempty() const { return items == 0; }
bool Q::isfull() const { return items == qsize; }
int Q::qcount() const { return items; }
// pridanie item (zakaznika) do Q
bool Q::enq(const Item & item)
{
if (isfull())
return false;
Node * add = new Node; //vytvori polozku
if (add == NULL) return false; // navrat pri chybe
add->item = item; // nastavevnie ukazatela
add->dalsi = NULL;
items++;
if (zaciatok == NULL) // pokial je polozka prazda
zaciatok = add; // umiestni ju na zaciatok
else
koniec->dalsi = add; //inak koniec
koniec = add; // nastavit ukazatel koniec na novu polozku
return true;
}
bool Q::deq(Item & item)
{
if (zaciatok == NULL)
return false;
item = zaciatok->item; // nastavi ukazatel na prvu polozku fronty
items--;
Node * temp = zaciatok; // ulozi adresu prvej polozky
zaciatok = zaciatok->dalsi; // nastavi ukazatel front na dalsiu polozku
delete temp; // zrusi predoslu prvu polozku
if (items == 0)
koniec = NULL;
return true;
}
// metoda triedy Zakaznik
void Zakaznik::set(long when)
{
casprocesu = std::rand() % 3 + 1;
prichod = when;
}
Kód:
#include "que.h"
#include <cstdlib>
#include <ctime>
const int MIN_PER_HR = 60;
bool novyZakaznik(double x);
int main()
{
using std::ios_base;
srand(time(0)); // nahodna inicializacia funkcie rand()
cout << "Pripadova studia: Bankomat Bank of H\n" <<
"Zadajte maximalnu dlzku fronty: ";
int qs;
cin >> qs;
Q line(qs);
cout << "Zadajte pocet simulovanych hodin: ";
int h; // pocet simulovanych hodin
cin >> h;
// jeden cyklus simulacie trva minutu
long cycleL = MIN_PER_HR * h; // pocet cyklov
cout << "Zadajte priemerny pocet zakaznikov za hodinu: ";
double zaH;
cin >> zaH;
double min_per_c; // priemerna doba medzi prichodom zakaznika -
min_per_c = zaH;
Item temp; // data noveho zakaznika
long turnaways = 0; // pocet odmietnutych zakaznikov
long customers = 0; // pocet zakaznikov vo fronte
long served = 0; // pocet obsluzenych zakaznikov
long sum_line = 0; // celkova dlzka fronty
int cakaci_cas = 0;
long doba_cakania = 0;
// beh simulacie
for (int cycle = 0; cycle < cycleL; cycle++)
{
if (novyZakaznik(min_per_c)) // novy zakaznik
{
if (line.isfull()) { turnaways++; }
else
{
customers++;
temp.set(cycle); // cycle cas prichodu
line.enq(temp); // prida noveho zakaznika do fronty
}
}
if (cakaci_cas <= 0 && !line.isempty())
{
line.deq(temp); // vyriadi dalsieho zakaznika
cakaci_cas = temp.pcas();
doba_cakania += cycle - temp.kedy();
served++;
}
if (cakaci_cas > 0) { cakaci_cas--; }
sum_line += line.qcount();
}
// vypis vysledkov
if (customers > 0) {
cout << "Pocet prijatych zakaznikov: " << customers << endl
<< "Pocet obsluzenych zakaznikov: " << served << endl
<< "Pocet odmietnutych zakaznikov: " << turnaways << endl
<< "Priemerna dlzka fronty: ";
cout.precision(2);
cout.setf(ios_base::fixed, ios_base::floatfield);
cout.setf(ios_base::showpoint);
cout << (double)sum_line / cycleL << endl
<< "\nPriemerna cakacia doba: " << (double)cakaci_cas / served << " minut.\n";
}
else { cout << "Niesu ziadny zakaznici.\n"; }
}
bool novyZakaznik(double x) { return (rand() * x / RAND_MAX < 1); }