I have a class that has an array of chars as an attribute.
class ClassA{
public:
ClassA( char *fileName );
char charArray[13][2];
};
ClassA
constructor reads in 26 values from a file, and loads them
into charArray
as follows.
ClassA::ClassA( fileName ){
ifstream file;
file.open( fileName );
int contactOne, contactTwo;
int pair=0;
while( !file.eof() ){
file >> contactOne;
file >> contactTwo;
if( !file.eof() ){
charArray[pair][0] = (contactOne+65); // convert to Alpha UpperCase
charArray[pair][1] = (contactTwo+65); // conv to Alpha UpperCase
pair++;
}
}
}
ClassA
is initialised in the constructor of another class, ClassB
where ClassB
contains a pointer to a ClassA
object, allowing ClassA
to be stored as an attribute of ClassB
.
class ClassA; // forward derive
class ClassB{
public:
ClassB( char **argv );
ClassA *a_class
};
ClassB's constructor:
ClassB::ClassB( argv ){
ClassA a( argv[1] );
a_class = &a;
}
In main
, i'm testing the association of ClassA
in ClassB
.
In a forloop I cout
all the values in charArray
in the following way.
int main( int argc, char **argv ){
ClassB b_class( argv );
for( int i=0; i < 13; i++ ){
cout << b_class.a_class->charArray[i][0] << endl;
cout << b_class.a_class->charArray[i][1] << endl;
}
}
When I construct ClassA
outside of ClassB
, cout << a.charArray[x][y];
works perfectly, outputting the various uppercase alphabet symbols from charArray
.
Indeed, even when I add the cout << a.charArray[x][y];
statement to the ClassA
constructor and initialise ClassA
using ClassB
constructor, the correct values are being loaded into charArray
, and the uppercase alphabet symbols are output.
However, when I execute what I have in main, the output from charArray
is very strange. The first few values of the array are as expected, but the last values are somewhat random, usually randomly placed blank values and question marks. It is as if, somehow the pointer has caused the values loaded into charArray
to be out of the correct range, or I am somehow accessing the wrong memory locations.
Any help would be much appreciated. Am I accessing ClassA
in a weird way? Is there a preferred way of having other classes as attributes to some class?
Unusual Output:
A
E
B
J
C
M
D
Z
?
?
?
y
Usual output:
A
E
B
J
C
M
D
Z
F
L
G
Y
H
X
I
V
K
W
N
R
O
Q
P
U
S
T
ClassA a( argv[1] );
defines a
as a local variable that will be destroyed and its memory rendered invalid on exit from the ClassB
constructor, leaving a_class
pointing at garbage.
Since you need a longer lifespan for a_class
you will have to new ClassA(argv[1]);
and ensure it is delete
d. I recommend looking into std::unique_ptr
.
Why do this in the first place? Instead since ClassA
has no dependency on ClassB
, ClassA
can be formally defined or its header file included before ClassB
is defined. Then you can remove the forward definition and:
class ClassB{
public:
ClassB( char **argv );
ClassA a_class
};
ClassB::ClassB( argv ):a_class(argv[1]){
}
To make the whole pointer mess go away.
while( !file.eof() )
and its ilk almost never work the way you're expecting. Read more here: Why is iostream::eof inside a loop condition considered wrong?
while( file >> contactOne >> contactTwo ){
charArray[pair][0] = (contactOne+65); // convert to Alpha UpperCase
charArray[pair][1] = (contactTwo+65); // conv to Alpha UpperCase
pair++;
}
Should do what you need.