Click here to Skip to main content
14,979,406 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Warning C6385 Reading invalid data from 'CRdr': the readable size is '(unsigned int)*108+4' bytes, but '216' bytes may be read.
C++
struct CReaders
{
	int		m_IntAddr{};//Card Reader number in ASC not HEX. CARD READER TABLE
	CStringA	m_HexAddr = _T("");//Card Reader Address in Hex, LAST Octet
	CStringA	m_Loc	= _T("");//Location of Card Reader, Text Description
	CStringA	m_Desc 	= _T("");//Description of Card Reader, Additional Text
	int		m_BUS{};	//WHICH COM PORT IS BEING USED
	BOOL		m_ELEVATOR{};
	CStringA	m_CmdLv = _T("");//max of "CMD_MAX"=15 command levels
	int		m_CmdLvInt[CMD_MAX]{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};//integer
	BOOL		m_VOID{};
	int		m_Type{};	//reader module motherboard type
volatile BOOL		m_GOOD_CHK{};	//USED ONLY IN OMU2 AND CHECKING
	BOOL		m_DISPLAY{};	//FOR USE IF L9 OR L10 DEVICES TO USE
	BOOL		m_DISPLAY_OFFLine{};//FOR DISPLAYING ON THE TRANSACTION 
};


//DB opened and start reading; how many records
  		m_ReaderSet->MoveFirst();
		do
		{
			m_ReaderCount++;	//unsigned int
			m_ReaderSet->MoveNext();
		}while(!m_ReaderSet->IsEOF());
	
		if(m_ReaderCount > READERS_MAX)
			m_ReaderCount = READERS_MAX;


		//if memory is inside CRdr, delete it
		if(CRdr)
			delete [] CRdr;
		CRdr = 0;
		CRdr = new  CReaders[m_ReaderCount+10];
		// INIT STRUCT TO ZERO //ONE BASED HERE! STARTS AT 1  

	for(c=0;c<=(int)m_ReaderCount+1;c++)
	{
		CRdr[c].m_BUS		= 0;
		CRdr[c].m_ELEVATOR	= FALSE;
		CRdr[c].m_GOOD_CHK	= TRUE;
		CRdr[c].m_IntAddr	= 0;
		CRdr[c].m_Type		= 0;
		CRdr[c].m_VOID		= FALSE;
		CRdr[c].m_DISPLAY	= FALSE;
		CRdr[c].m_DISPLAY_OFFLine= FALSE;
		CRdr[c].m_Loc	        = _T("");//Warning C6385 is here, 
 		CRdr[c].m_HexAddr	= _T("");
		CRdr[c].m_CmdLv		= _T("");
 		CRdr[c].m_Desc		= _T("");
	}

CStringA packs to 8 bits. Column for m_Loc is nvarchar(50), null in the DB. In the
program, its pulled out via CStringA:
RFX_Text(pFX, _T("[Loc]"), m_Loc); //m_Loc is a CStringA

My Question is: How do I remove this warning?

The compiler is VS2019 "all warnings" and I discovered this by using the Analize tool on VS2019.
Compiler set to "Use Multi-Byte Character Set"
The compiler doesn't know the DB so the 50 nvarchar is unknown to the compiler.
I can't do anything with the CStringA in the structure except
initialize it with a NULL or nothing.
Wanted to set its limit but can't be don't during initializing. I can "Release buffer, Set limit" later but that doesn't get rid of the warning.

Compiler is using the standard 8 bit packing for structures.
I would like to give more code but this is a part of 300,000 line code I made. The program works fine and has been for years but this is the
last annoyance I would like to tackle but don't know how, any clues?
This is one example:
I have 10 other structures with CStrings as members that have the same warnings.

One other struct is using CTime m_EndSched{}; as a member and getting the same warning.

Warning C6385 Reading invalid data from 'SchdLvl': the readable size is '(unsigned int)*100+4' bytes, but '200' bytes may be read.
DB=EndDate(datetime,null)

The very last resort to change all CStrings to char but that means using sprintf/scopy/strcat/sprintf_s (which will be banned soon)or the format command on a CString in reverse.



What I have tried:

I have tried to init the CString in the struct but its illegal. I tried packing to 2,4,8,16 bits using #pragma pack(n) or in the compiler itself. I tried to "Release set limit" to the CString later in the code but the compiler still has the warning.
Posted
Updated 13-Aug-20 3:10am
v2
Comments
Rick York 12-Jun-20 17:16pm
   
No, sprintf, strcpy, and strcat will not be banned, nor will MBCS. They are standard library functions and Microsoft does not have the authority to ban them from the library.

If they do remove them from VS's RTL then you can use your own implementations of them. I am certain there will plenty to choose from.
inlandchris1 13-Jun-20 0:38am
   
Thank you for that. My impression was they were scheduled to be removed because of the virus scare. I will make a mental note.
KarstenK 13-Jun-20 4:33am
   
a possibble solution is to use TCHAR array of a fitting size. And for for loop limits are looking strange.
inlandchris1 13-Jun-20 4:37am
   
Well thats a good idea but its the same energy to replace all the CStrings with chars[?], just a lot of work but that is my last resort, thanks for the reply
inlandchris1 13-Jun-20 4:40am
   
I agree about the loop, just wanted to allocate more than I needed to prevent an overrun but really, all I need is 1 more on allocation.

Check the value of CMD_MAX - at a guess it's 108 + 4 bytes (i.e. 28 32-bit integers) and the actual size needed is bigger.
   
v2
Comments
inlandchris1 13-Jun-20 0:43am
   
CMD_MAX is only a #define (was, now its "constexpr auto") of 15, meaning maximum of 15 for that array.
My guess the 108+4 is the CString because what is needed is 200 which is nvarchar(50) is a char of 50 long. A char is 4 bytes long time 50 == 200. So, the analyzed part of VS2019 did read the DB and found it could read up to 200. But why is the CString limited to 108+4?
OriginalGriff 13-Jun-20 3:34am
   
"A char is 4 bytes long"

Where on earth did you get that idea?
A char is either 1 bytes or 2 bytes depending on the definition of _UNICODE in your compilation options ...
inlandchris1 13-Jun-20 4:34am
   
Yes, nice reply, its the compaction in the struct when the compiler is set for 8, like what I have been writing about. Selection is a choice of: 2,4,8,16. The default is 8 and makes the char worth 4, ok?
The fact is you don't need to do most of the things you are doing to those string members. It is already initialized to be empty so the initializer is not needed. It has a clear method so you can call that instead of assigning an empty string to it.

Also, these lines don't make sense :
C++
    CRdr = new  CReaders[m_ReaderCount+10];
    // INIT STRUCT TO ZERO //ONE BASED HERE! STARTS AT 1

for(c=0;c<=(int)m_ReaderCount+1;c++)
because you aren't initializing all of the data. Why allocate it if it isn't going to be used? A better way to do this would be :
C++
 // determine exactly how many will be used
int readersUsed = m_ReaderCount + 1;  // or what ever that should be
readers = new CReaders[ readersUsed ];
for( c = 0; c < readersUsed; ++c )
   readers[ c ].Initialize();
You seem to have arbitrary values for the number of readers and then the number that are initialized. Those need to be the SAME number, what ever that is.

Note - I used an Initialize method of the CReader class because it needs one if you do not have its initializers set up the way they need to be.

-edit- here's how I would do that :
C++
struct CReaders
{
    CStringA    m_HexAddr;   //Card Reader Address in Hex, LAST Octet
    CStringA    m_Loc;       //Location of Card Reader, Text Description
    CStringA    m_Desc;      //Description of Card Reader, Additional Text
    CStringA    m_CmdLv;     //max of "CMD_MAX"=15 command levels
    int         m_CmdLvInt[ CMD_MAX ];
    int         m_IntAddr;   //Card Reader number in ASC not HEX. CARD READER TABLE
    int         m_BUS;       //WHICH COM PORT IS BEING USED
    int         m_Type;      //reader module motherboard type
    BOOL        m_ELEVATOR;
    BOOL        m_VOID;
    BOOL        m_GOOD_CHK;  //USED ONLY IN OMU2 AND CHECKING
    BOOL        m_DISPLAY;   //FOR USE IF L9 OR L10 DEVICES TO USE
    BOOL        m_DISPLAY_OFFLine;  //FOR DISPLAYING ON THE TRANSACTION 

    CReaders()
    {
        Initialize();
    }

    void Initialize()
    {
        m_HexAddr.Empty();
        m_Loc.Empty();
        m_Desc.Empty();
        m_CmdLv.Empty();

        for( inr n = 0; n < CMD_MAX; ++n )
            n_CmdLvInt[ n ] = 0;

        m_IntAddr         = 0;
        m_BUS             = 0;
        m_Type            = 0;
        m_ELEVATOR        = FALSE;
        m_VOID            = FALSE;
        m_GOOD_CHK        = TRUE;
        m_DISPLAY         = FALSE;
        m_DISPLAY_OFFLine = FALSE;
    }
};
this arrangement initializes the data in the constructor
   
v3
Rick Y.,thank you for your solution. I did not think outside of the box on initializing the members, mindset on ‘C’ language, not C++. I did not know you could put the functions inside the struct but when you really think about, C++ is a giant struct, everything held tightly. I tested this and it works as the best way to init structs! But, I still get the same warning about the CString. I tried to do a PreAllocate of 200 in the initialization of the struct but that didnt deter the warnings. The DB shows 50 nvarchars width and in a struct pack of 8, the char is worth 4, times 50=200.
This s the most efficient initialization method I ever saw and I want to thank you for sharing, really appreciate it.
The .clear() you are using for the CStrings I dont have. I believe that is a method “using namespace System” which I am not using the /clr on the compiler. So, I just omit the inits on the CStrings and just preAllocate the CStrings.
The allocation of the ‘new’ plus 10 was only a stupid fear of overrunning the variable, switched back to your idea of +1 which is a better idea.
Thank you,
Craig C.
   
v2
Comments
Rick York 13-Jun-20 18:40pm
   
clear() is member of std::basic_string - I forgot you were using CString and I never use it. I believe it has an Empty() method that will do the same thing but it should be created empty so it is not necessary there.

BTW - this should be posted as a comment to my post and not another solution, just as I am replying to your's.
inlandchris1 14-Jun-20 10:29am
   
I am curious why you don't like CString(). I have looked into string() and it doesn't have many functions as CString does but is there a performance problem?
Rick York 14-Jun-20 12:35pm
   
I work with a lot of STL and internal library stuff and I decided to choose one string class and stick with it. It's not really that I don't like it. It's just that I try to avoid all MFC collection and template classes and use STL things instead.
inlandchris1 14-Jun-20 13:44pm
   
Thank you. MFC is almost gone since 2010 but I started this program in 2008 and now stuck with it for repairs and upgrades as Windows upgrades. Soon, no more upgrades on the program as MFC will be permanently gone. Too bad, many programs to this one employer; about 500,000 lines of old code.
inlandchris1 15-Jun-20 15:34pm
   
Rick, OK, finally found the trouble with reading invalid data from the Struct. I had an extra CString member that I didn't use or initialize. It apparently interfered with some of the other members being CString or char *, first time to see that but happily got it. Structs need to be tight, no slack, just thought I would pass it along.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900