I'm getting random character output

I can compile this code properly. But when I run it, the output has some lines like "►¶☻☺╚‼☻☺" this. Can you help me to solve this problem.

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
#include <iostream>
#include <cstring>
#include <cstdlib>
using namespace std;


class date{
	char *p;
	public:
	date(const char *s);
	~date() { cout << "Destructing" << endl; delete [] p;}
	
	char *get() {return p;}	
};

date::date(const char *s){
	int l;
	l = strlen(s) + 1;
	p = new char [l];
	if (!p) { cout << "Allocation error" << endl; exit (1);}
    strcpy(p, s); 
}


void show(date x){
    char *s;
	s = x.get();
	cout << s << endl;
	
}   



int main(){
	date sdate("04/06/21");
	date xdate("00/00/00");
	
	xdate = sdate;
	show(sdate);
	show(xdate);
	
	cout << sdate.get() << " " << xdate.get() << endl;
    
	return 0;
}
Try to avoid single-letter variables like 'l'. I mistook it for a 1. At least call it something like 'len', that way people will immediately recognize it.

Are you allowed to just use strings instead of char arrays?
Your main issue is that you are copying your date object when you pass it to show, but this then calls the destructor for the copied object, which deletes the same dynamic memory as the original object.

When dealing with dynamic memory or other unmanaged resources, you should follow the "rule of three" (AKA "rule of five", but we can ignore move constructors for learning purposes).
https://en.wikipedia.org/wiki/Rule_of_three_(C%2B%2B_programming)

To avoid making a copy, you can pass date by reference
1
2
3
4
show(date& x)
{
    ...
}


Even better would be to make your get function be const,
1
2
3
4
char *get() const
{
    return p;
}	


And then pass by const reference
1
2
3
4
show(const date& x)
{
    ...
}


But passing by copy (value) should not break the code, so you should implement a copy constructor.

Also, on line 19, p = new char [l]; failed, it would throw an exception, not return null, so your if statement is dead code.

I also question the broad design of the code itself. You call this a "date" object, yet all it does is hold a string that was passed to it. That string could be "puppy". Usually, people would want to use "dates" for actually date/time calculations. See an example of date/time library at: https://howardhinnant.github.io/date/date.html
Last edited on
You also need a copy assignment function as well.

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
#include <iostream>
#include <utility>
#include <cstring>
#include <cstdlib>

class date {
	char* p {};

public:
	date(const char* s);
	~date() { delete[] p; }
	date(const date& d);
	date& operator=(date d);

	char* get() const { return p; }
};

date::date(const char* s) : p(std::strcpy(new char[strlen(s) + 1], s)) {}
date::date(const date& d) : p(std::strcpy(new char[strlen(d.p) + 1], d.p)) {}

date& date::operator=(date d)
{
	std::swap(p, d.p);
	return *this;
}

void show(const date& x) {
	std::cout << x.get() << '\n';
}

int main() {
	date sdate("04/06/21");
	date xdate("00/00/00");

	xdate = sdate;

	show(sdate);
	show(xdate);

	std::cout << sdate.get() << " " << xdate.get() << '\n';
}



04/06/21
04/06/21
04/06/21 04/06/21

Thank you, I missed that.
Thank you guys so much, I need to read a little about your responses.
Topic archived. No new replies allowed.