I'm getting random character output

Apr 9, 2021 at 2:26pm
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;
}
Apr 9, 2021 at 3:04pm
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 Apr 9, 2021 at 3:10pm
Apr 9, 2021 at 5:37pm
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

Apr 9, 2021 at 6:08pm
Thank you, I missed that.
Apr 9, 2021 at 8:21pm
Thank you guys so much, I need to read a little about your responses.
Topic archived. No new replies allowed.