Warum sind TCHAR buffer[4] keine 4 Zeichen?



  • Hallo,

    mir ist da beim schreiben eines Code mal was aufgefallen, was ich in der Vergangenheit einfach ignoriert habe und die Größe des Buffer erhöht habe. Nun möchte ich aber dennoch mal wissen warum das so ist wie es ist, dazu folgender simpler Code:

    unsigned long num = 5485245;
    	TCHAR szBuffer[18];
    	unsigned char buffer;
    	tstring hexStr;
    	for (int i = 0; i < 4; i++)
    	{
    		buffer = (char)(num >> (i * 8) & 0xFF);
    
    		SecureZeroMemory(szBuffer, _tcslen(szBuffer));
    		_stprintf_s(szBuffer, _T("%02X"), buffer);
    
    		hexStr.insert(0, szBuffer);
    	}
    
    	tcout << "HEX: " << hexStr << "\n";
    

    Wenn ich TCHAR szBuffer[18]; auf 17 setzte, kommt der fehler

    Run-Time Check Failure #2 - Stack around the variable 'szBuffer' was corrupted.
    

    Und die 18 wundert mich ja auch schon, ich nehme doch extra TCHAR damit ich mir keine Gedanken machen muss ob ein Buchstabe nun 4 oder 8 oder 16 Byte hat (darum auch tcout und tstring, sind typedef für wstring oder eben string)

    Wieso kommt dieser Fehler?



  • Irgendwie sind da mehrere komische Sachen drin. Einmal

    SecureZeroMemory(szBuffer, _tcslen(szBuffer));
    

    Wieso nutzt du dort _tcslen ? Das zählt doch die Anzahl der Zeichen in szBuffer, der ist aber gerade noch nicht initialisiert also kann da alles mögliche rauskommen. Eigentlich willst du eher das hier:

    SecureZeroMemory(szBuffer, sizeof(szBuffer));
    

    Dann die andere Sache ist dein _stprintf_s Aufruf. Der Zweite Parameter ist doch eigentlich die Größe des Strings oder nicht? Versuch mal sowas:

    _stprintf_s(szBuffer, sizeof(szBuffer)/sizeof(szBuffer[0]), _T("%02X"), buffer);
    

    Ich hab gerade aber auch ein Windows System zur Hand also kann ich nichts testen.



  • Oh, stimmt, nicht _tcslen sondern sizeof ... das ist sogar genau der Fehler.

    Ich mache SecureZeroMemory weil es sich in einer schleife befindet und ich sicher stellen möchte das absolut leer ist, den oft kopiere ich dann Daten per memcopy und das sind nicht immer \0-strings. Ist die Einstellung falsch vorher immer zu löschen?



  • Eigentlich ist das vorherige Löschen unnötig. Es gibt schließlich zwei Fälle: Entweder arbeitet man mit Nullterminierten Daten oder nicht. Wenn es nullterminiert ist, dann hängen String Funktionen wie sprintf und Konsorten sowieso eine abschließende \0 dran. Oder die Daten sind nicht nullterminiert, aber dann ist es eh egal ob am Ende nocht irgendein Müll kommt weil man die Größe separat speichern muss. Man sollte nur nicht anfangen zu mischen zwischen beiden Varianten.



  • in welchem header befindet sich tstring?



  • Ich vermute bei tstring handelt es sich um ein typedef, sprich

    using tstring = std::basic_string<TCHAR>;
    

    tcout wohl analog.



  • static std::wistream& tcin = std::wcin;
    	static std::wostream& tcout = std::wcout;
    	static std::wostream& tcerr = std::wcerr;
    	static std::wostream& tclog = std::wclog;
    
    	typedef		std::wstring			tstring;
    	typedef		std::wios			tios;
    

    steht in der tstring-header


Log in to reply