Obsah fóra
PravidláRegistrovaťPrihlásenie




Odpovedať na tému [ Príspevkov: 6 ] 
AutorSpráva
Offline

Užívateľ
Užívateľ
Obrázok užívateľa

Registrovaný: 16.12.15
Prihlásený: 11.03.22
Príspevky: 21
Témy: 9
Príspevok NapísalOffline : 13.05.2016 20:37

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 delete

Edit: 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); }


Offline

Skúsený užívateľ
Skúsený užívateľ
Obrázok užívateľa

Registrovaný: 17.07.11
Prihlásený: 29.12.20
Príspevky: 1516
Témy: 3
Príspevok NapísalOffline : 13.05.2016 21:17

Citácia:
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ť.

Toto je pravda. Tam sa ale ukazateľ prehodí inam a zmaže sa temp. Takže sa zmaže "bývalý" začiatok. V istých prípadoch to môže byť správne (napr. mažem prvý prvok zoznamu).

K tomu patrí aj odpoveď - ukazateľ ukazuje na nejaké miesto v pamäti. Takže áno, je úplne jedno, ako sa volá tá premenná (ukazateľ), ktorá na ten kus pamäti ukazuje. Môže ich byť aj viac naraz. A ten kus pamäti sa uvoľní (delete) ktorýmkoľvek z nich.

Citácia:
tak ak tomu správne chápem, ukazovateľ na štruktúru zaciatok, bude ukazovať na nič? Teda nebude mať pridelenú pamäť?

Ukazateľ bude väčšinou ukazovať na adresu 0, čo môžeš chápať ako vyhradenú adresu pre nič. Takže v podstate áno. Skôr sa tomu hovorí "prázdny ukazateľ".







_________________
Na súkromné správy týkajúce sa problémov, ktoré sa riešia vo fóre, neodpovedám!
Offline

Užívateľ
Užívateľ
Obrázok užívateľa

Registrovaný: 16.12.15
Prihlásený: 11.03.22
Príspevky: 21
Témy: 9
Príspevok Napísal autor témyOffline : 13.05.2016 21:52

Vďaka za odpovede, ešte ale nemám ujasnené s tými ukazovateľmi na NULL. Toto všetko čo je tu popísané už chápem, ale v knihe sa ešte píše že môžem použiť delete na ukazateľ ktorý ukazuje na NULL. Teda ak si to dobre pamätám. Potom ak ukazuje ukazovateľ na nič, ako sa môže použiť delete? Čo sa vtedy stane? Nehovoriac o tom, že na tú 0 môže ukazovať viacero ukazovateľov.


Offline

Užívateľ
Užívateľ
Ukazovatel a operator delete c++

Registrovaný: 24.08.12
Prihlásený: 09.02.19
Príspevky: 59
Témy: 0
Príspevok NapísalOffline : 14.05.2016 13:31

Ukazatel na NULL je ukazatel nikam*, znamená to že neobsahuje platnou hodnotu, takže na NULL můžou ukazovat třeba všechny které v programu máš. A před každou manipulací se získaným ukazatelem je potřeba zkontrolovat že v něm není NULL, jinak program spadne!
Takže se dá předpokládat že delete nejdřív zkontroluje jestli v ukazateli je nějaká hodnota, a když najde NULL, tak nic neudělá.

* přesněji na úplný začátek RAM, kde má důležitá data operační systém, takže každý program který mu tam začne hrabat okamžitě bez milosti odstřelí ;-)







_________________
"Existuje pouze jeden člověk, který má méně přátel než Bill Gates, a tím je Saddám Husajn." (Paul Grayson)
Offline

Užívateľ
Užívateľ
Obrázok užívateľa

Registrovaný: 22.08.11
Prihlásený: 14.12.23
Príspevky: 2361
Témy: 11
Príspevok NapísalOffline : 14.05.2016 15:35

Delete mozes pouzit aj na null pointer, nic sa nestane, delete si to kontroluje sam.


Offline

Skúsený užívateľ
Skúsený užívateľ
Obrázok užívateľa

Registrovaný: 17.07.11
Prihlásený: 29.12.20
Príspevky: 1516
Témy: 3
Príspevok NapísalOffline : 14.05.2016 20:50

delete NULL je prázdna operácia, nič sa nestane, to je pravda.

Ale nie úplne súhlasím s tým, že NULL ukazuje na nejaké dáta operačného systému. Teda aspoň nie dnes, keď máme virtualizaciu pamäte.

A to že program spadne je síce pravda, ale to kvôli dereferencii NULL. Tým, že NULL ukazuje na nič, tak to proste počítač nevie dereferencovať (získať hodnotu z adresy). Čiže kontrola na NULL je nutná pred každou dereferenciou ukazateľa, ak si nie si istý, čo v ňom môže byť.







_________________
Na súkromné správy týkajúce sa problémov, ktoré sa riešia vo fóre, neodpovedám!
Odpovedať na tému [ Príspevkov: 6 ] 


Podobné témy

 Témy  Odpovede  Zobrazenia  Posledný príspevok 
Táto téma je zamknutá, nemôžete posielať nové príspevky alebo odpovedať na staršie. C++ ukazovatel a odkaz

v Assembler, C, C++, Pascal, Java

13

1800

16.08.2010 11:58

Ďuri Zobrazenie posledných príspevkov

V tomto fóre nie sú ďalšie neprečítané témy. C++ handle,operátor *...

v Assembler, C, C++, Pascal, Java

2

835

02.04.2009 19:01

László145 Zobrazenie posledných príspevkov

V tomto fóre nie sú ďalšie neprečítané témy. Operator priradenia C++

v Assembler, C, C++, Pascal, Java

0

1286

12.09.2009 23:05

peter100 Zobrazenie posledných príspevkov

V tomto fóre nie sú ďalšie neprečítané témy. Ukazovatel clenskej statickej funckie a jej vyvolanie C++

v Assembler, C, C++, Pascal, Java

3

413

10.06.2017 18:16

BX Zobrazenie posledných príspevkov

V tomto fóre nie sú ďalšie neprečítané témy. C++ new / delete

v Assembler, C, C++, Pascal, Java

1

652

01.12.2008 21:15

ado21 Zobrazenie posledných príspevkov

V tomto fóre nie sú ďalšie neprečítané témy. Nefunguje ukazovateľ jasu

v Ostatné

2

380

15.08.2012 21:21

MiSCHo_20 Zobrazenie posledných príspevkov

V tomto fóre nie sú ďalšie neprečítané témy. ukazovatel teploty :P

v Benchmarky a diagnostické programy

17

2547

02.09.2007 21:09

Jaro Zobrazenie posledných príspevkov

V tomto fóre nie sú ďalšie neprečítané témy. MiniAPP- Ukazovateľ ping

v Ostatné programy

6

399

08.01.2016 10:14

Lessik Zobrazenie posledných príspevkov

V tomto fóre nie sú ďalšie neprečítané témy. Ukazovateľ batérie (Ubuntu)

v Ostatné programy

3

598

28.11.2010 10:41

W.u.n.j.o Zobrazenie posledných príspevkov

V tomto fóre nie sú ďalšie neprečítané témy. upload skript - ukazovatel priebehu

v PHP, ASP

1

560

26.01.2009 17:44

emer Zobrazenie posledných príspevkov

V tomto fóre nie sú ďalšie neprečítané témy. softver - ukazovateľ skore na futbal

v Grafické programy

1

372

12.12.2014 9:16

don jebot Zobrazenie posledných príspevkov

V tomto fóre nie sú ďalšie neprečítané témy. Automaticky presúvať ukazovateľ myši na predvolené tlačidlo

v Operačné systémy Microsoft

0

399

06.06.2012 17:45

fagi853 Zobrazenie posledných príspevkov

V tomto fóre nie sú ďalšie neprečítané témy. Ternarni operator.

v Assembler, C, C++, Pascal, Java

7

465

27.01.2014 8:16

BX Zobrazenie posledných príspevkov

V tomto fóre nie sú ďalšie neprečítané témy. Virtuálny operátor

v Smartfóny a tablety

2

395

18.10.2020 19:28

tatko Tom Zobrazenie posledných príspevkov

V tomto fóre nie sú ďalšie neprečítané témy. ternary operator

v JavaScript, VBScript, Ajax

1

398

20.06.2013 22:57

BX Zobrazenie posledných príspevkov

V tomto fóre nie sú ďalšie neprečítané témy. ternárny operátor

v Assembler, C, C++, Pascal, Java

2

1309

12.11.2012 23:32

ik112 Zobrazenie posledných príspevkov


Nemôžete zakladať nové témy v tomto fóre
Nemôžete odpovedať na témy v tomto fóre
Nemôžete upravovať svoje príspevky v tomto fóre
Nemôžete mazať svoje príspevky v tomto fóre

Skočiť na:  

Powered by phpBB Jarvis © 2005 - 2024 PCforum, webhosting by WebSupport, secured by GeoTrust, edited by JanoF
Ako väčšina webových stránok aj my používame cookies. Zotrvaním na webovej stránke súhlasíte, že ich môžeme používať.
Všeobecné podmienky, spracovanie osobných údajov a pravidlá fóra