C++ Stack implementation – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu
Reklama

C++ Stack implementation – C / C++ – Fórum – Programujte.comC++ Stack implementation – C / C++ – Fórum – Programujte.com

 

Spuštěný nový filmový web Filmožrouti.cz — vše o Avengers, Pacific Rim, Thor, Star Wars…
Stamp
~ Anonymní uživatel
3 příspěvky
18. 6. 2018   #1
-
0
-

Ahoj, chcel som implementovať Stack v C++ pomocou OOP a pola (vektor som nechcel).
Stack.cpp
 

// Stack.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "Stack.h"
#include <assert.h>
#include <iostream>

Stack::Stack()
{
	Stack::sizeOfStack = 0;
}

Stack::~Stack() {
	delete[] Stack::st;
}

void Stack::push(int num) {
	Stack::st[sizeOfStack++] = num;
}

int Stack::size() {
	return Stack::sizeOfStack;
}

bool Stack::isEmpty() {
	return Stack::sizeOfStack == 0;
}

int Stack::pop() {
	assert(!(Stack::sizeOfStack == 0));
	return Stack::st[sizeOfStack--];
}

void Stack::print() {
	for (int i = 0; i < Stack::sizeOfStack; ++i)
		std::cout << Stack::st[i] << " ";
	std::cout << std::endl;
}

Stack.h
 

#ifndef STACK
#define STACK

class Stack {

	private:
		unsigned short sizeOfStack;
		int *st = new int[sizeOfStack];

	public:
		bool isEmpty();
		int pop();
		void print();
		void push(int num);
		int size();
		Stack();
		~Stack();
		
};
#endif

Otázkou je, že prečo to funguje? Skúšal som iba jeden prípad kedy som to naplnil 4 hodnotami a skúšal
som popovať a fungovalo to. Plán bol dynamicky zväčšovať pole po push() , avšak nejak som na to zabudol , pustil a ide to aj takto. Prepisujem v tomto prípade pamäť ktorú nevlastním? 

Nahlásit jako SPAM
IP: 78.98.4.–
gna
~ Anonymní uživatel
668 příspěvků
19. 6. 2018   #2
-
0
-

Inicializace st proběhne před konstruktorem a proměnná sizeOfStack v té době není inicializovaná.

Pokud má malou hodnotu, tak zapisuješ za to pole. Velikost alokované paměti se zarovnává na nějakou hodnotu, takže za tím polem může být prostor, který lze bez problému přepsat. Ale většinou je to jen pár bajtů, které když překročíš, tak by to nejpozději při delete[] mělo sletět.

Nebo má sizeOfStack takovou hodnotu, že to pole je dostatečně velké.

Mimochodem, pop() máš špatně.

Nahlásit jako SPAM
IP: 213.211.51.–
Stamp
~ Anonymní uživatel
3 příspěvky
19. 6. 2018   #3
-
0
-

Dík za odpoveď, potom mi to aj nejako došlo že nie je inicializovaná takže v nej bude asi nejaká veľká hodnota.
Trochu som to opravil, prechádzam z C a jediný spôsob čo mi napadol bol cez realloc čo mi nepríde moc C++ :-)
Za hocijaké postrehy budem rád 
 

// Stack.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "Stack.h"
#include <assert.h>
#include <iostream>
#include <stdlib.h>
#include <vector>

Stack::Stack()
{
	Stack::sizeOfStack = 5;
	Stack::numbersInStack = 0;
	Stack::st = new int[Stack::sizeOfStack];
}

Stack::~Stack() {
	delete[] Stack::st;
}

void Stack::push(int num) {
	Stack::st[numbersInStack++] = num;
	if (numbersInStack == sizeOfStack) {
		sizeOfStack *= 2;
		st = static_cast<int *>(std::realloc(st,sizeof(int) * sizeOfStack));
	}
}

int Stack::size() {
	return Stack::numbersInStack;
}

bool Stack::isEmpty() {
	return Stack::numbersInStack == 0;
}

int Stack::pop() {
	assert(!(Stack::numbersInStack == 0));
	return Stack::st[--numbersInStack];
}

void Stack::print() {
	for (int i = 0; i < Stack::numbersInStack; ++i)
		std::cout << Stack::st[i] << " ";
	std::cout << std::endl;
}
// Stack.h
#ifndef STACK
#define STACK

class Stack {
	private:
		unsigned short sizeOfStack;
		unsigned short numbersInStack;
		int *st = NULL;

	public:
		bool isEmpty();
		int pop();
		void print();
		void push(int num);
		int size();
		Stack();
		~Stack();
		
};
#endif 
Nahlásit jako SPAM
IP: 78.98.24.–
KIIV
~ Moderátor
+43
God of flame
19. 6. 2018   #4
-
0
-

#3 Stamp
realloc patri k malloc, neni ani trochu dobrej napad pouzivat ho s new. To same jako se nemicha new a free. Kdo vi jakou neplechu to pak udela pri uvolnovani pomoci delete[]. Hlavne proto, ze interne ma new[] jeste taky ulozenou velikost pred samotnym polem (vrati se ale pointer az na pole). Obzvlaste u objektu to bude delat silenou paseku. Vector taky zvetsuje tak, ze udela dalsi pole a puvodni prvky presune.

Dalsi zasadni problem je co se stane, pokud udelas kopii objektu? Ja nevim, treba predani do funkce hodnotou. Pointer bude stejny v obou instancich a jakmile funkce skonci, zavola se delete[] a najednou mas v puvodnim stacku dangling pointer (pointer na neplatna data) a pak se to samozrejme bude pokouset o druhe uvolneni jiz uvolnene pamete. Taktez, pokud zmenis data, tak se projevi i navenek ikdyz to necekas (ale ne velikost a tak, jen data v poli). Bude to chtit nastudovat  Rule of Three / Rule of Five.

Nahlásit jako SPAM
IP: 89.24.50.–
Program vždy dělá to co naprogramujete, ne to co chcete...
MilanL+1
Věrný člen
19. 6. 2018   #5
-
0
-

#4 KIIV
ahoj, zajímavé téma.

Chápu to dobře, že pokud objekt chci předávat funkcím hodnotou a pro návratový typ, měl bych mít nadefinovanou obsluhu těch přiřazovacích operátorů, tzn hlubokou kopii, aby se to chovalo správně?

Nahlásit jako SPAM
IP: 91.139.9.–
KIIV
~ Moderátor
+43
God of flame
19. 6. 2018   #6
-
0
-

#5 MilanL
Pokud si v objektu vytvaris/zabiras nejake resourcy (a to neni jen alokace pameti), tak je to nutne.

Jinak napriklad u kopirovani (asi hlavne prirazenim) je nutne pohlidat jestli to neni ten samy objekt. Co se stane, kdyz mas nejakou spravu resourcu a nekdo udela   obj = obj; Proste uplne nejdulezitejsi je copy constructor a copy assigment operator.

Move constructor a move assigment operator jsou dulezite, pokud se objekt "registruje" nekam jinam, do nejakych observeru nebo tak. Pokud presunes objekt, zmeni se vlastne jeho umisteni v pameti a callbacky obvykle obsahuji pointer na danny objekt a pointer na nejakou jeho metodu.

Kazdopadne, pokud se predava objekt, tak se pouzivaji zasadne reference. Pokud se objekt nema uvnitr funkce menit, tak konstantni reference. Pak se spolehlive zabrani kopii.

Nahlásit jako SPAM
IP: 89.24.50.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Stamp
~ Anonymní uživatel
3 příspěvky
19. 6. 2018   #7
-
0
-

No trochu som to Rule of three postudoval, tak dufam ze to je aspon o nieco lepsie :-) 

// Stack.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "Stack.h"
#include <assert.h>
#include <iostream>
#include <stdlib.h>
#include <vector>

Stack::Stack()
{
	Stack::sizeOfStack = 5;
	Stack::numbersInStack = 0;
	Stack::st = new int[Stack::sizeOfStack];
}

Stack::Stack(const Stack &n) : // copy constructor
	st(new int[n.numbersInStack]), 
	numbersInStack(n.numbersInStack), 
	sizeOfStack(n.sizeOfStack)
{
	std::copy(n.st,n.st+n.numbersInStack,st);
}

Stack& Stack::operator=(const Stack &source) { // copy assignment constructor
	int *newData = new int[source.numbersInStack];
	numbersInStack = source.numbersInStack;
	sizeOfStack = source.sizeOfStack;
	std::copy(source.st, source.st + source.numbersInStack, newData);
	delete[] st;
	st = newData;
	return *this;
}

Stack::~Stack() { // destructor
	delete[] Stack::st;
}

void Stack::push(int num) {
	Stack::st[numbersInStack++] = num;
	if (numbersInStack == sizeOfStack) {
		sizeOfStack *= 2;
		int *newSt = new int[sizeOfStack];
		std::copy(st, st + numbersInStack, newSt);
		delete[] st;
		st = newSt;
	}
}

int Stack::size() {
	return Stack::numbersInStack;
}

bool Stack::isEmpty() {
	return Stack::numbersInStack == 0;
}

int Stack::pop() {
	assert(!(Stack::numbersInStack == 0));
	return Stack::st[--numbersInStack];
}

void Stack::print() {
	for (int i = 0; i < Stack::numbersInStack; ++i)
		std::cout << Stack::st[i] << " ";
	std::cout << std::endl;
}
#ifndef STACK
#define STACK
#include <algorithm>
class Stack {
	private:
		unsigned short sizeOfStack;
		unsigned short numbersInStack;
		int *st = NULL;

	public:
		bool isEmpty();
		int pop();
		void print();
		void push(int num);
		int size();
		Stack();
		Stack(const Stack &n);
		~Stack();
		Stack &operator=(const Stack &source);
		
};
#endif 
Nahlásit jako SPAM
IP: 78.98.24.–
Zjistit počet nových příspěvků

Přidej příspěvek

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 59 hostů

Podobná vlákna

Interface <> Implementation — založil adamlevine

Stack — založil Qwerty

Stack — založil Robo

Jak změnit stack DS? — založil vanasi

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032018 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý