[ 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 | 9
NapísalOffline : 13.05.2016 20:37 | Ukazovatel a operator delete c++

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 | 3
NapísalOffline : 13.05.2016 21:17 | Ukazovatel a operator delete c++

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 | 9
Napísal autor témyOffline : 13.05.2016 21:52 | Ukazovatel a operator delete c++

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 | 0
NapísalOffline : 14.05.2016 13:31 | Ukazovatel a operator delete c++

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 | 11
NapísalOffline : 14.05.2016 15:35 | Ukazovatel a operator delete c++

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 | 3
NapísalOffline : 14.05.2016 20:50 | Ukazovatel a operator delete c++

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!
 [ Príspevkov: 6 ] 


Ukazovatel a operator delete c++



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

1846

16.08.2010 11:58

Ďuri

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

C++ handle,operátor *...

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

2

884

02.04.2009 19:01

László145

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

Operator priradenia C++

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

0

1340

12.09.2009 23:05

peter100

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

473

10.06.2017 18:16

BX

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

C++ new / delete

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

1

691

01.12.2008 21:15

ado21

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

Ukazovateľ batérie (Ubuntu)

v Ostatné programy

3

648

28.11.2010 10:41

W.u.n.j.o

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

Nefunguje ukazovateľ jasu

v Ostatné

2

416

15.08.2012 21:21

MiSCHo_20

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

ukazovatel teploty :P

v Benchmarky a diagnostické programy

17

2579

02.09.2007 21:09

Jaro

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

MiniAPP- Ukazovateľ ping

v Ostatné programy

6

450

08.01.2016 10:14

Lessik

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

upload skript - ukazovatel priebehu

v PHP, ASP

1

597

26.01.2009 17:44

emer

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

softver - ukazovateľ skore na futbal

v Grafické programy

1

433

12.12.2014 9:16

don jebot

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

469

06.06.2012 17:45

fagi853

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

Virtuálny operátor

v Smartfóny a tablety

2

449

18.10.2020 19:28

tatko Tom

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

Ternarni operator.

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

7

519

27.01.2014 8:16

BX

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

ternary operator

v JavaScript, VBScript, Ajax

1

458

20.06.2013 22:57

BX

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

ternárny operátor

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

2

1369

12.11.2012 23:32

ik112



© 2005 - 2025 PCforum, edited by JanoF