my template code seems unusable

I describe the template class as follows for a stack, Which uses a specific type to generalize the concept of stacks.

Complete code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include <iostream>
#include <string.h>
using namespace std;
struct Node{
    char data;
    Node* link = nullptr;
    Node(char d){data=d;}
};
template<typename T>
struct Nod{
    T data;
    Nod *link = nullptr;
    Nod(T y){data=y;}
};
template<class Tx>
class ModStack{
    private:
        Nod<Tx> *top = nullptr;
    public:
        void Push(Tx x){
            if(!top){
                top->data = x;
                top->link = nullptr;
                return;
            }
            Nod<Tx> *n = new Nod<Tx>(x);
            n->link = top;
            top = n;
        }
        void Pop(){
            if(!top){cout<<"Stack is empty!"<<endl;return;}
            top = top->link;
        }
        Tx Top(){
            if(!top){cout<<"Stack is empty!"<<endl;return NULL;}
            return top->data;
        }
        bool IsEmpty(){
            if(!top)
                return true;
            return false;
        }
};
Node *head = nullptr;
void Insert(char a){
    Node* to_insert = new Node(a);
    if(!head){
        head = to_insert;
        return;
    }else{
        Node* t = head;
        while(t->link){
            t = t->link;
        }
        t->link = to_insert;
    }
}
main(){
    string b = "tiresome12";
    for(int i=0;i<10;i++){
        Insert(b[i]);
    }
    Node *n = head;
    ModStack<Node *> * stck = new ModStack<Node *>();
    while(n){
        stck->Push(n);
        cout<<n<<endl;
        n = n->link;
    }
    stck->Push(head);
    cout<<stck->Top()<<endl;
    while(!stck->IsEmpty()){
        cout<<stck->Top()<<endl;
        stck->Pop();
    }
}

Using this in x64 architecture windows machine, with C++11 shows successful compilation but do not show any output.
Last edited on
Use code tags and post a complete program.
Are you also unfamiliar with a complete program?
Obviously your program is not complete since it has no header includes
and it says "Node" in main, which of course doesn't exist since you called your struct "Nod".
Now it's fine
foo.cpp:22:22: runtime error: member access within null pointer of type 'Nod<Node *>'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior foo.cpp:22:22 in 
foo.cpp:22:22: runtime error: store to null pointer of type 'Node *'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior foo.cpp:22:22 in 
UndefinedBehaviorSanitizer:DEADLYSIGNAL
==10579==ERROR: UndefinedBehaviorSanitizer: SEGV on unknown address 0x000000000000 (pc 0x55efdb8daf00 bp 0x7ffc213993b0 sp 0x7ffc21399330 T10579)
==10579==The signal is caused by a WRITE memory access.
==10579==Hint: address points to the zero page.
    #0 0x55efdb8daf00  (a.out+0x2ef00)
    #1 0x55efdb8da3cd  (a.out+0x2e3cd)
    #2 0x7f262040fb24  (/usr/lib/libc.so.6+0x27b24)
    #3 0x55efdb8b236d  (a.out+0x636d)

UndefinedBehaviorSanitizer can not provide additional info.
SUMMARY: UndefinedBehaviorSanitizer: SEGV (a.out+0x2ef00) 
==10579==ABORTING


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#include <iostream>
#include <string> //string for std::string (no .h)
using namespace std;
/* ¿what's the purpose of this class?
struct Node{
    char data;
    Node* link = nullptr;
    Node(char d){data=d;}
};
*/
template<typename T>
struct Nod{
    T data;
    Nod *link = nullptr;
    Nod(T y){data=y;}
};
template<class Tx>
class ModStack{
    private:
        Nod<Tx> *top = nullptr;
    public:
        void Push(Tx x){
            if(!top){
                //top->data = x; //top is null, you can't dereference it
                top = new Nod(x); //allocate memory for it
                top->link = nullptr; //now it is valid and can be dereferenced
                return;
            }
            Nod<Tx> *n = new Nod<Tx>(x);
            n->link = top;
            top = n;
        }
        void Pop(){
            if(!top){cout<<"Stack is empty!"<<endl;return;}
            top = top->link; //memory leak
        }
        Tx Top(){
            if(!top){ //¡indent!
              cout<<"Stack is empty!"<<endl;
              return NULL; //¿what if NULL is not a proper Tx?
            }
            return top->data;
        }
        bool IsEmpty(){
          return not top; //be concise
          /*
            if(!top)
                return true;
            return false;
           */
        }
        /* No appropriate destructor (leak)
         * No appropriate copy-constructor nor assignment operator
         */
};
/* this seems to implement a global queue
Node *head = nullptr;
void Insert(char a){
    Node* to_insert = new Node(a);
    if(!head){
        head = to_insert;
        return;
    }else{
        Node* t = head;
        while(t->link){
            t = t->link;
        }
        t->link = to_insert;
    }
}
 */

int // main must return int
main(){
    string b = "tiresome12";
    /* Create an object, not a pointer, no need for new
     * It stores chars (or that's what the user knows)
     */
    ModStack<char> stck;
    for(int i=0;i<10;i++){
      stck.Push(b[i]);
    }
    while(not stck.IsEmpty()){
        cout<<stck.Top()<<endl;
        stck.Pop();
    }
}

Last edited on
?

Last edited on
ne555, Use case was to use the head for as the type for template class. And creating a general Stack of Objects.
Although, Can you explain the part of memory leak.
Perhaps:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include <iostream>
#include <string>

template<typename T>
struct Node {
	T data {};
	Node* link {};

	Node(const T& y) : data(y) {}
};

template<class T>
class ModStack {
private:
	Node<T>* top {};

public:
	ModStack() {}

	~ModStack() {
		while (top) {
			const auto nxt {top->link};

			delete top;
			top = nxt;
		}
	}

	ModStack(const ModStack&) = delete;
	ModStack& operator=(ModStack) = delete;

	void Push(const T& x) {
		const auto n {new Node<T>(x)};

		n->link = top;
		top = n;
	}

	void Pop() {
		if (!top) {
			std::cout << "Stack is empty!\n";
			return;
		}

		top = top->link;
	}

	T Top() const {
		if (!top) {
			std::cout << "Stack is empty!\n";
			return {};
		}

		return top->data;
	}

	bool IsEmpty() const {
		return !top;
	}
};

int main() {
	const std::string b {"tiresome12"};
	ModStack<char> stck;

	for (const auto& c : b)
		stck.Push(c);

	for (; !stck.IsEmpty(); stck.Pop())
		std::cout << stck.Top() << ' ';
}



2 1 e m o s e r i t

I forgot Garbage collection is manual in cpp, so careless
Rightly used C++ doesn't produce garbage so there is no need for garbage collection.
The problem is that too many old books and crappy courses teach very C-ish old stuff.
@dutch: ¿what part is causing confusion?

> Use case was to use the head for as the type for template class.
¿ah?

> And creating a general Stack of Objects.
it is general
ModStack<char> stores characters
ModStack<int> stores numbers
ModStack<peanuts> stores peanuts


@seeplus:
1
2
3
4
5
6
7
8
	void Pop() {
		if (!top) {
			std::cout << "Stack is empty!\n";
			return;
		}

		top = top->link;
	}
memory leak
I see that ok, But destructors are really necessary?
And deleting the node from the memory too, Cause it might effect the memory space if large number of entries are to be inserted.
@ne555 Thanks for explanation, Will Constructors and destructors be useful for template program?
Will Constructors and destructors be useful for template program?
Yes
Memory leak.


Correct. Thanks. I was in too much of a hurry...... More haste, less speed...

1
2
3
4
5
6
7
8
9
10
11
void Pop() {
		if (!top) {
			std::cout << "Stack is empty!\n";
			return;
		}

		auto tmp {top};

		top = top->link;
		delete tmp;
	}

Last edited on
Topic archived. No new replies allowed.