Mistake when writing an object from another one

Hello,

Here is my problem :
I have 2 classes in my program. The first one builds an object A with 4 members variables. The second one builds dynamically an object B which is an array of a certain number of objects A. I wrote all the functions and overloads necessary.

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
#pragma once
#include <string>
#include <iostream>
using namespace std;


class CFleur
{
public:
	CFleur();
	CFleur(string, string, double, double);
	friend ostream& operator << (ostream&, CFleur&);
	friend istream& operator >> (istream&, CFleur&);
	string Get_nom();
	string Get_couleur();
	double Get_calibre();
	double Get_prix();
	void Set_nom(string);
	void Set_couleur(string);
	void Set_calibre(double);
	void Set_prix(double);
	~CFleur();

private:
	string Nom;
	string Couleur;
	double Calibre;
	double Prix;
};


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#pragma once
#include "Fleur.h"

class CBouquet
{
public:
	CBouquet();
	CBouquet(CBouquet&);
	CBouquet& operator = (CBouquet);
	CBouquet operator + (CFleur);
	friend CBouquet operator +(CFleur, CBouquet);
	friend ostream& operator << (ostream&, CBouquet&);
	friend istream& operator >> (istream&, CBouquet&);
	~CBouquet();

private:
	int N;
	CFleur* Bouquet;
};


In my main program, I create an object B and I want to write it with "cin", at the moment when I must inform the first variable member of the first object A of the object B, the program crashes. It says Something like "Access violation".

1
2
3
4
5
6
7
#include "Bouquet.h"

void main()
{
	CBouquet B;
	cin >> B;
}


To me, my program is nice written and no mistakes are popping out.

Do you have any idea of the possible mistake I've done ?

Thank you.
Last edited on
It should always be int main(), not void.

The code above doesn't show in full all the function definitions, such as constructors/destructors. Most likely there is an uninitialised pointer.
Ok, then here is the full code of both classes :

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
#include "Fleur.h"



CFleur::CFleur()
{
	Nom = "";
	Couleur = "";
	Calibre = 0;
	Prix = 0;
}

CFleur::CFleur(string N, string C, double c, double p)
{
	Nom = N;
	Couleur = C;
	Calibre = c;
	Prix = p;
}

ostream& operator << (ostream& os, CFleur& F)
{
	os << "Nom : " << F.Nom << ", Couleur : " << F.Couleur << ", Calibre : " << F.Calibre << ", Prix : " << F.Prix << endl;
	return os;
}

istream& operator >> (istream& is, CFleur& F)
{
	cout << "Saisir le nom de la fleur : " << endl;
	is >> F.Nom;
	cout << "Saisir la couleur de la fleur : " << endl;
	is >> F.Couleur;
	cout << "Saisir le calibre de la fleur : " << endl;
	is >> F.Calibre;
	cout << "Saisir le prix de la fleur : " << endl;
	is >> F.Prix;
	return is;
}

string CFleur::Get_nom()
{
	return Nom;
}

string CFleur::Get_couleur()
{
	return Couleur;
}

double CFleur::Get_calibre()
{
	return Calibre;
}

double CFleur::Get_prix()
{
	return Prix;
}

void CFleur::Set_nom(string N)
{
	Nom = N;
}

void CFleur::Set_couleur(string C)
{
	Couleur = C;
}

void CFleur::Set_calibre(double c)
{
	Calibre = c;
}

void CFleur::Set_prix(double P)
{
	Prix = P;
}

CFleur::~CFleur()
{
}


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
88
#include "Bouquet.h"



CBouquet::CBouquet()
{
	N = 0;
	Bouquet = NULL;
}

CBouquet::CBouquet(CBouquet& B)
{
	N = B.N;
	Bouquet = new CFleur[N];
	for (int i = 0; i < N; i++)
	{
		Bouquet[i] = B.Bouquet[i];
	}
}

CBouquet& CBouquet::operator=(CBouquet B)
{
	if (Bouquet)
		delete[] Bouquet;
	N = B.N;
	Bouquet = new CFleur[N];
	for (int i = 0; i < N; i++)
	{
		Bouquet[i] = B.Bouquet[i];
	}
	return *this;
}

CBouquet CBouquet::operator+(CFleur F)
{
	CBouquet B;
	B.N = N + 1;
	B.Bouquet = new CFleur[B.N];
	for (int i = 0; i < N; i++)
	{
		B.Bouquet[i] = Bouquet[i];
	}
	B.Bouquet[B.N] = F;
	return B;
}

CBouquet operator+(CFleur F, CBouquet B)
{
	CBouquet b;
	b = B;
	b.N = B.N + 1;
	b.Bouquet = new CFleur[b.N];
	b.Bouquet[0] = F;
	for (int i = 1; i < b.N; i++)
	{
		b.Bouquet[i] = B.Bouquet[i];
	}
	return b;
}

ostream& operator << (ostream& os, CBouquet& B)
{
	os << "Votre bouquet est actuellement compose de " << B.N << "fleur(s) :" << endl;
	for (int i = 0; i < B.N; i++)
	{
		os << B.Bouquet[i] << endl;
	}
	return os;
}

istream& operator >> (istream& is, CBouquet& B)
{
	cout << "Veuillez composer votre bouquet :" << endl;
	cout << "Indiquez le nombre de fleur(s) composant le bouquet :" << endl;
	is >> B.N;
	cout << "Ajouter y maintenant les fleurs :" << endl;
	for (int i = 0; i < B.N; i++)
	{
		is >> B.Bouquet[i];
	}
	return is;
}

CBouquet::~CBouquet()
{
	if (Bouquet)
		delete[] Bouquet;
}


By the way, I've always written void main() and not int main(). Is it grave ?
Thank you for posting the rest of the code.

As I suspected the pointer was initialised to NULL, then attempted to use as though it was an array.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
istream& operator >> (istream& is, CBouquet& B)
{
	cout << "Veuillez composer votre bouquet :" << endl;
	cout << "Indiquez le nombre de fleur(s) composant le bouquet :" << endl;
	is >> B.N;
	
	if (B.Bouquet)
		delete[] B.Bouquet;
		
	B.Bouquet = new CFleur[B.N];
	
	cout << "Ajouter y maintenant les fleurs :" << endl;
	for (int i = 0; i < B.N; i++)
	{
		is >> B.Bouquet[i];
	}
	return is;
}


Note I added line 10 which solved the problem, and lines 7 and 8 to avoid any memory leak.

Regarding void main(). That is not standard C++. Yes, some compilers will allow it, but others do not. Mine gave this error output and refused to compile at all:
3	11	main.cpp	[Error] '::main' must return 'int'
28		Makefile.win	recipe for target 'main.o' failed


It is best to start with good habits when learning, then your code should always work in any compiler (provided the compiler conforms to standards for C++).

Oh great ! It works ! Thank you !

So I have to add the line 10 each time I use or call an object B in a function or overload ? (if I initialized it as NULL in the constructor).
I'd say any time your code modifies the value of N, you should be checking that the pointer Bouquet is also modified so it stores the same number of elements. Most of your existing code already does that - though I didn't test all of it or verify whether or not it is correct.
Line 43 should be B.Bouquet[N] = F;
Line 56 should be b.Bouquet[i] = B.Bouquet[i-1];
Well, maybe you'll be able to help on overloading the operator + in this case :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
CCatalogue CCatalogue::operator+(CFleur F)//Probleme
{
	CCatalogue Ct;
	Ct.Nf = Nf + 1;
	Ct.Catalogue = new CFleur[Ct.Nf];
	for (int i = 0; i < Nf + 1; i++)
	{
		Ct.Catalogue[i] = Catalogue[i];
	    if (i == Nf)
	    {
	    Ct.Catalogue[Nf + 1] = F;
		}
	}
	return Ct;
}


When I add an object CFleur to the object CCatalogue in my main program, it crashes.
1
2
3
4
	CCatalogue C("C:/Users/pmmpmm/Documents/catalogue.txt");
	cout << C;
	CFleur F("test","t",2,3);
	C + F;


It's weird cause when I just let this in the overload, it already crashes... I don't know why.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
CCatalogue CCatalogue::operator+(CFleur F)//Probleme
{
	CCatalogue Ct;
	Ct.Nf = Nf + 1;
	//Ct.Catalogue = new CFleur[Ct.Nf];
	//for (int i = 0; i < Nf + 1; i++)
	//{
	//	Ct.Catalogue[i] = Catalogue[i];
	//    if (i == Nf)
	//    {
	//    Ct.Catalogue[Nf + 1] = F;
	//	}
	//}
	return Ct;
}


Do you see my mistake ?
At line 5 you allocate space for objects 0 to Nf. At line 11 you set object Nf+1, which is out of bounds.
At line 5 you allocate space for objects 0 to Nf. At line 11 you set object Nf+1, which is out of bounds. My advice is to use Nf or Ct.Nf consistently though the function.
Then I should use them like this ?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 CCatalogue CCatalogue::operator+(CFleur F)//Probleme
{
	CCatalogue Ct;
	Ct.Nf = Nf + 1;
	Ct.Catalogue = new CFleur[Ct.Nf];
	for (int i = 0; i < Nf; i++)
	{
		Ct.Catalogue[i] = Catalogue[i];
	    if (i == Nf)
	    {
	    Ct.Catalogue[Ct.Nf] = F;
		}
	}
	return Ct;
}


And I don't understand my mistake at the line 5. Can you write the line corrected please ?
Last edited on
You almost have it. Starting at the for loop, I think the code should be:
1
2
3
4
5
6
7
// Copy All of my flowers
for (int i = 0; i < Nf; i++) {
	Ct.Catalogue[i] = Catalogue[i];
}
// Add the new one.
Ct.Catalogue[Nf] = F;
return Ct;

Ok, I tried but it didnt work :(

Everything works if I don't copy the objects :
Ct.Catalogue[i] = Catalogue[i];

It means if I write this it works (but not completely because objects are not copied) :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
 CCatalogue CCatalogue::operator+(CFleur F)//Probleme
{
	CCatalogue Ct;
	Ct.Nf = Nf + 1;
	Ct.Catalogue = new CFleur[Ct.Nf];
	for (int i = 0; i < Nf; i++)
	{
	    if (i == Nf)
	    {
	    Ct.Catalogue[Ct.Nf] = F;
		}
	}
	return Ct;
}


So I think the problem comes from copying the objects but I don't get why ...
Last edited on
Ok, I tried but it didnt work :(
That's because you didn't try the code i gave you ;)

CCatalogue CCatalogue::operator+(CFleur F)//Probleme
{
CCatalogue Ct;
Ct.Nf = Nf + 1;
Ct.Catalogue = new CFleur[Ct.Nf];

// Copy All of my flowers
for (int i = 0; i < Nf; i++) {
Ct.Catalogue[i] = Catalogue[i];
}
// Add the new one.
Ct.Catalogue[Nf] = F;

return Ct;
}
Topic archived. No new replies allowed.