| | |
| Stránka: 1 z 1
| [ Príspevkov: 6 ] | |
Autor | Správa |
---|
Registrovaný: 16.12.15 Prihlásený: 11.03.22 Príspevky: 21 Témy: 9 |
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); }
|
|
Registrovaný: 17.07.11 Prihlásený: 29.12.20 Príspevky: 1516 Témy: 3 | Napísal BX: 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! |
|
Registrovaný: 16.12.15 Prihlásený: 11.03.22 Príspevky: 21 Témy: 9 | Napísal autor témy Elendil: 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.
|
|
Registrovaný: 24.08.12 Prihlásený: 09.02.19 Príspevky: 59 Témy: 0 | Napísal faraon: 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) |
|
Registrovaný: 22.08.11 Prihlásený: 14.12.23 Príspevky: 2361 Témy: 11 | Napísal magic: 14.05.2016 15:35 | |
|
Delete mozes pouzit aj na null pointer, nic sa nestane, delete si to kontroluje sam.
|
|
Registrovaný: 17.07.11 Prihlásený: 29.12.20 Príspevky: 1516 Témy: 3 | Napísal BX: 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! |
|
| Stránka: 1 z 1
| [ Príspevkov: 6 ] | |
Podobné témy | Témy | Odpovede | Zobrazenia | Posledný príspevok |
---|
| C++ ukazovatel a odkaz v Assembler, C, C++, Pascal, Java | 13 | 1800 | 16.08.2010 11:58 Ďuri | | C++ handle,operátor *... v Assembler, C, C++, Pascal, Java | 2 | 835 | 02.04.2009 19:01 László145 | | Operator priradenia C++ v Assembler, C, C++, Pascal, Java | 0 | 1286 | 12.09.2009 23:05 peter100 | | Ukazovatel clenskej statickej funckie a jej vyvolanie C++ v Assembler, C, C++, Pascal, Java | 3 | 413 | 10.06.2017 18:16 BX | | C++ new / delete v Assembler, C, C++, Pascal, Java | 1 | 652 | 01.12.2008 21:15 ado21 | | Nefunguje ukazovateľ jasu v Ostatné | 2 | 380 | 15.08.2012 21:21 MiSCHo_20 | | ukazovatel teploty :P v Benchmarky a diagnostické programy | 17 | 2547 | 02.09.2007 21:09 Jaro | | MiniAPP- Ukazovateľ ping v Ostatné programy | 6 | 399 | 08.01.2016 10:14 Lessik | | Ukazovateľ batérie (Ubuntu) v Ostatné programy | 3 | 598 | 28.11.2010 10:41 W.u.n.j.o | | upload skript - ukazovatel priebehu v PHP, ASP | 1 | 560 | 26.01.2009 17:44 emer | | softver - ukazovateľ skore na futbal v Grafické programy | 1 | 372 | 12.12.2014 9:16 don jebot | | Automaticky presúvať ukazovateľ myši na predvolené tlačidlo v Operačné systémy Microsoft | 0 | 399 | 06.06.2012 17:45 fagi853 | | Ternarni operator. v Assembler, C, C++, Pascal, Java | 7 | 465 | 27.01.2014 8:16 BX | | Virtuálny operátor v Smartfóny a tablety | 2 | 395 | 18.10.2020 19:28 tatko Tom | | ternary operator v JavaScript, VBScript, Ajax | 1 | 398 | 20.06.2013 22:57 BX | | ternárny operátor v Assembler, C, C++, Pascal, Java | 2 | 1309 | 12.11.2012 23:32 ik112 |
| 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
|
|