Array corruption

A

Active8

Hi:

This prob "magically" stopped and I'm not sure if I can recreate it,
but thought I'd share it and maybe learn something.

#include "stdafx.h"
#include <stdlib.h>
#include <math.h>
#include <fstream.h> //iostream.h

// yes, I'll fix those includes, too

class Yi
{
public:
Yi();

int Number(char bits){return _myNumber[bits];
}

private:
int _myNumber[64];
int _myReverse[64];
//int place1; // prevents array element corruption.
char _myShortName[64][32];
char _myName[64][64];
};

#include <iostream.h>
#include <string.h>
#include "yi.structure.h"

// ditto with those includes

Yi::Yi()
{
int num[64] = {2,23,8,20,16,35,45,12,
15,52,39,53,62,56,31,33,
7,4,29,59,40,64,47,6,
46,18,48,57,32,50,28,44,
24,27,3,42,51,21,17,25,
36,22,63,37,55,30,49,13,
19,41,60,61,54,38,58,10,
11,26,5,9,34,14,43,1};

char short_name[64][32] = {"Creative","Receptive",

// blah blah

char name[64][64] = {"The Creative","The Receptive",
// more blah

for(int i=0;i<64;i++)
{
_myNumber = num;
_myReverse[ num ] = i;
strcpy(_myName,name);
strcpy(_myShortName,short_name);
}
}

See that odd comment

//int place1; // prevents array element corruption.

?

That's what I had to do to make it work. What would happen was I'd
instanciate a Yi and look up the number of a symbol using

int Number(char bits){return _myNumber[bits];

based on 6 bits (char bits, would you guess?) which represent the
symbol.

Number() always returned 21 - saw it in the debugger. I get lost when
the debugger steps into the library code and couldn't figure out
exactly where the problem was, just that the return value of Number()
was always 21.

//int place1; // prevents array element corruption.

was the fix except at the time int _myReverse[64]; wasn't needed and
I wouldnt be surprised if int _myReverse[64]; is what's keeping things
working today.

Structure member alignment has always been set at 8 bytes FWIW

I thought the array was corrupted because of the fix, but am not sure
if I checked the whole array at the time. maybe it wassomething else.

Mike
 
A

Active8

I just wanted to ask if anyone had any ideas what was going on and to
say

Thanks!

Mike

Sorry. Even lame yahoo lets one delete their own post and start from
scratch. Maybe I just don't see a delete link.
 
M

Mark Holland

Active8 said:
Hi:

This prob "magically" stopped and I'm not sure if I can recreate it,
but thought I'd share it and maybe learn something.

#include "stdafx.h"
#include <stdlib.h>
#include <math.h>
#include <fstream.h> //iostream.h

// yes, I'll fix those includes, too

class Yi
{
public:
Yi();

int Number(char bits){return _myNumber[bits];
}

private:
int _myNumber[64];
int _myReverse[64];
//int place1; // prevents array element corruption.
char _myShortName[64][32];
char _myName[64][64];
};

#include <iostream.h>
#include <string.h>
#include "yi.structure.h"

// ditto with those includes

Yi::Yi()
{
int num[64] = {2,23,8,20,16,35,45,12,
15,52,39,53,62,56,31,33,
7,4,29,59,40,64,47,6,
46,18,48,57,32,50,28,44,
24,27,3,42,51,21,17,25,
36,22,63,37,55,30,49,13,
19,41,60,61,54,38,58,10,
11,26,5,9,34,14,43,1};

for(int i=0;i<64;i++)
{
_myNumber = num;
_myReverse[ num ] = i;
strcpy(_myName,name);
strcpy(_myShortName,short_name);
}
}


Consider what happens when i == 21.
Then num == 64.
When you do _myReverse[ num ] = i, this is actually _myReverse[64]
= 21;
In other words, you are writing one element beyond the end of array
_myReverse.
This was previously writing over your member _myShortName, but after
you added the extra int as padding this is what gets overwritten
instead.

HTH
Mark
 
A

Active8

This prob "magically" stopped and I'm not sure if I can recreate it,
but thought I'd share it and maybe learn something.
#include "stdafx.h"
#include <stdlib.h>
#include <math.h>
#include <fstream.h> //iostream.h
// yes, I'll fix those includes, too
class Yi
{
public:
Yi();
int Number(char bits){return _myNumber[bits];
}
private:
int _myNumber[64];
int _myReverse[64];
//int place1; // prevents array element corruption.
char _myShortName[64][32];
char _myName[64][64];
};
#include <iostream.h>
#include <string.h>
#include "yi.structure.h"
// ditto with those includes
Yi::Yi()
{
int num[64] = {2,23,8,20,16,35,45,12,
15,52,39,53,62,56,31,33,
7,4,29,59,40,64,47,6,
46,18,48,57,32,50,28,44,
24,27,3,42,51,21,17,25,
36,22,63,37,55,30,49,13,
19,41,60,61,54,38,58,10,
11,26,5,9,34,14,43,1};

for(int i=0;i<64;i++)
{
_myNumber = num;
_myReverse[ num ] = i;
strcpy(_myName,name);
strcpy(_myShortName,short_name);
}
}


Consider what happens when i == 21.
Then num == 64.
When you do _myReverse[ num ] = i, this is actually _myReverse[64]
= 21;
In other words, you are writing one element beyond the end of array
_myReverse.
This was previously writing over your member _myShortName, but after
you added the extra int as padding this is what gets overwritten
instead.

HTH
Mark


Thanks Mark man. I'll double check that. Damn! I know better and just
hate seeing that num-1 in my index. But not as much as VB defaulting
to base index (?) of 1. Not sure if the reverse array was even there
yet. I commented out that padding and the very first element of
short_name[] is getting hosed. I forget studying the ansi/iso std
preping for brain bench, but IIRC class members get initialized from
bottom to top I might need to think this through backwards.

You know what? Even when I let it get corrupted, I out put bot long
and short names and they match, I wouldn't expect that if my index was
off by one.

I'll play around and come back if I have more probs or anything of
value to contrib.

And duh! The delete (remove) link is in "more options" right where I
left it.

Thanks Guru.
Mike
 
B

BobR

Active8 said:
Hi:
This prob "magically" stopped and I'm not sure if I can recreate it,
but thought I'd share it and maybe learn something.

#include "stdafx.h"

Non-standard header, don't use (in this NG).
#include <stdlib.h>
#include <math.h>
#include <fstream.h> file://iostream.h
// yes, I'll fix those includes, too

#include <cstdlib> // <stdlib.h>

Only include headers you are using.

Is this homework? If it is, just ignore the following suggestions.

/*
class Yi{ public:
Yi();
int Number(char bits){ return _myNumber[bits]; }
private:
int _myNumber[64];
int _myReverse[64];
file://int place1; // prevents array element corruption.
char _myShortName[64][32];
char _myName[64][64];
};
*/

// --- Yi.h ---
#include <string>
#include <vector>

class Yi{ public:
Yi( std::size_t ); // note: acts like default Ctor.
int Number( char bits ){
size_t indx( bits);
if( indx > myNumber.size() ){
return 0;
} // if(indx)
return myNumber.at( indx );
} // Number(char)
private:
std::vector<int> myNumber;
std::vector<int> myReverse;
std::vector<std::string> myShortName;
std::vector<std::string> myName;
};
// ......

// --- Yi.cpp ---
#include <string>
#include <algorithm> // for copy()
#include "Yi.h" // or whatever you name it

int num[64] = {2,23,8,20,16,35,45,12,
15,52,39,53,62,56,31,33,
7,4,29,59,40,64,47,6,
46,18,48,57,32,50,28,44,
24,27,3,42,51,21,17,25,
36,22,63,37,55,30,49,13,
19,41,60,61,54,38,58,10,
11,26,5,9,34,14,43,1};

std::string short_name[64] = {"Creative","Receptive",
// > // blah blah
};
std::string name[64] = {"The Creative","The Receptive",
// > // more blah
};

Yi::Yi( std::size_t size = 65 ) : myReverse(size){ // note colon
std::copy( num, num + sizeof( num )/sizeof( *num ),
std::back_inserter( myNumber ) ); // _myNumber=num;
std::copy( name, name + sizeof( name )/sizeof( *name ),
std::back_inserter( myName ) );
std::copy( short_name,
short_name + sizeof( short_name )/sizeof( *short_name ),
std::back_inserter( myShortName ) );
for( size_t i(0); i < myNumber.size(); ++i ){
myReverse.at( myNumber.at( i ) ) = i;
} // for(i)
} // Yi::Yi() Ctor
// ......

// --- YiMain.cpp ---
#include <iostream>
#include "Yi.h" // or whatever you name it

int main(){
Yi yipe; // note how def' size acts like default Ctor.
cout<<"Yi yipe yipe.Number('B'-'A')="
<<yipe.Number('B'-'A')<<std::endl;
return 0;
} // main()

// out: Yi yipe yipe.Number('B'-'A')=23
 
J

Jim Langston

Active8 said:
Hi:

This prob "magically" stopped and I'm not sure if I can recreate it,
but thought I'd share it and maybe learn something.

#include "stdafx.h"
#include <stdlib.h>
#include <math.h>
#include <fstream.h> //iostream.h

// yes, I'll fix those includes, too

class Yi
{
public:
Yi();

int Number(char bits){return _myNumber[bits];
}

private:
int _myNumber[64];
int _myReverse[64];
//int place1; // prevents array element corruption.
char _myShortName[64][32];
char _myName[64][64];
};

#include <iostream.h>
#include <string.h>
#include "yi.structure.h"

// ditto with those includes

Yi::Yi()
{
int num[64] = {2,23,8,20,16,35,45,12,
15,52,39,53,62,56,31,33,
7,4,29,59,40,64,47,6,

Mark is correct, the 64 in yoru data is the offense. Arrays in C and C++
are 0 bound, they go from 0 to length - 1. So to make this program work as
designed, each and every number should be one less. Here in the data is
probalby the best place.
46,18,48,57,32,50,28,44,
24,27,3,42,51,21,17,25,
36,22,63,37,55,30,49,13,
19,41,60,61,54,38,58,10,
11,26,5,9,34,14,43,1};

char short_name[64][32] = {"Creative","Receptive",

// blah blah

char name[64][64] = {"The Creative","The Receptive",
// more blah

for(int i=0;i<64;i++)
{
_myNumber = num;
_myReverse[ num ] = i;


and here it becomes for one interatation:
_myReverse[ 64 ] = i;
but _myReverse only goes from [0] to [63]
strcpy(_myName,name);
strcpy(_myShortName,short_name);
}
}

See that odd comment

//int place1; // prevents array element corruption.

?

That's what I had to do to make it work. What would happen was I'd
instanciate a Yi and look up the number of a symbol using

int Number(char bits){return _myNumber[bits];

based on 6 bits (char bits, would you guess?) which represent the
symbol.

Number() always returned 21 - saw it in the debugger. I get lost when
the debugger steps into the library code and couldn't figure out
exactly where the problem was, just that the return value of Number()
was always 21.

//int place1; // prevents array element corruption.

was the fix except at the time int _myReverse[64]; wasn't needed and
I wouldnt be surprised if int _myReverse[64]; is what's keeping things
working today.

Structure member alignment has always been set at 8 bytes FWIW

I thought the array was corrupted because of the fix, but am not sure
if I checked the whole array at the time. maybe it wassomething else.


Further comment, preceeding any variable with an underscore _ is considered
bad form. There are many instances where variable names preceeded by an
underscore are reserved. There are various rules so it's better just to not
do it at all. Personally, private member variables I append an underscore
at the end.

myShortNames_
myname_
 
A

Active8

Non-standard header, don't use (in this NG).

It's a VC thing. Goes with stdafx.cpp - Precompiled headers - they're
turned off now (they don't compile) but it's in the project in case I
use it. The stdafx.h includes stuff the whole app uses and doesn't
change often - think that's the idea. Everything gets precompiled up
to stdafx.h and it savdes time. This little proggy doesn't warrant all
that right now but when it grows up...
#include <cstdlib> // <stdlib.h>

Only include headers you are using.

They're used elsewhere.
Is this homework? If it is, just ignore the following suggestions.

No. It going to be a windows app when it grows up. For now it's for
friends to try out I Ching without investing in books, coins, stalks,
etc.

So thanks for the alternate code. I should try to find STL solutions
"before" I start coding. I like what I see so far. Easy to read and
probably more foolproof. Thanks.

Mike
/*> class Yi{ public:
Yi();
int Number(char bits){ return _myNumber[bits]; }
private:
int _myNumber[64];
int _myReverse[64];
file://int place1; // prevents array element corruption.
char _myShortName[64][32];
char _myName[64][64];
};

*/

// --- Yi.h ---
#include <string>
#include <vector>

class Yi{ public:
Yi( std::size_t ); // note: acts like default Ctor.
int Number( char bits ){
size_t indx( bits);
if( indx > myNumber.size() ){
return 0;
} // if(indx)
return myNumber.at( indx );
} // Number(char)
private:
std::vector<int> myNumber;
std::vector<int> myReverse;
std::vector<std::string> myShortName;
std::vector<std::string> myName;
};
// ......

// --- Yi.cpp ---
#include <string>
#include <algorithm> // for copy()
#include "Yi.h" // or whatever you name it

int num[64] = {2,23,8,20,16,35,45,12,
15,52,39,53,62,56,31,33,
7,4,29,59,40,64,47,6,
46,18,48,57,32,50,28,44,
24,27,3,42,51,21,17,25,
36,22,63,37,55,30,49,13,
19,41,60,61,54,38,58,10,
11,26,5,9,34,14,43,1};

std::string short_name[64] = {"Creative","Receptive",
// > // blah blah
};
std::string name[64] = {"The Creative","The Receptive",
// > // more blah
};

Yi::Yi( std::size_t size = 65 ) : myReverse(size){ // note colon
std::copy( num, num + sizeof( num )/sizeof( *num ),
std::back_inserter( myNumber ) ); // _myNumber=num;
std::copy( name, name + sizeof( name )/sizeof( *name ),
std::back_inserter( myName ) );
std::copy( short_name,
short_name + sizeof( short_name )/sizeof( *short_name ),
std::back_inserter( myShortName ) );
for( size_t i(0); i < myNumber.size(); ++i ){
myReverse.at( myNumber.at( i ) ) = i;
} // for(i)
} // Yi::Yi() Ctor
// ......

// --- YiMain.cpp ---
#include <iostream>
#include "Yi.h" // or whatever you name it

int main(){
Yi yipe; // note how def' size acts like default Ctor.
cout<<"Yi yipe yipe.Number('B'-'A')="
<<yipe.Number('B'-'A')<<std::endl;
return 0;
} // main()

// out: Yi yipe yipe.Number('B'-'A')=23
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top