Eigenartiges Verhalten in String-Klasse

jccTeq

Erfahrenes Mitglied
Hallo,

edit: by the way... wir arbeiten mit Visual Studio 6.0 / Visual C++ unter Windows 2000.

normalerweise sagt man ja, daß ein PC genau das macht, auf was man ihn programmiert hat. Nicht so diese Kiste hier... hab hier ein Problem, das keiner meiner Kollegen (Ingeneure dabei) versteht. Ich mache das da:

Code:
CString xxx = "HALLO";

aber nach dem Aufruf ist der String xxx leer. Er wird nicht initialisiert. Das selbe Konstrukt habe ich an diversen anderen Stellen auch. Überall funktioniert's. Nur in dieser Funktion nicht. Und es gibt keinen sichtbaren Unterschied zu den anderen Funktionen. Keine versteckten Kommentarzeichen, keine Sonderzeichen... 1:1 kopiert. Und funktioniert nicht.

Wir haben eine String-Template-Klasse selbstgebaut, die ebenfalls Zuweisungsoperatoren etc. hat. Auch mit dieser Klasse tritt dieses Problem auf. Und auch wieder NUR in dieser Funktion. Überall anders funktioniert das. Wir machen da sowas:

Code:
String bla = "TEST";

bla += "HALLO";
bla += "BLUBB";

Als Ergebnis dieser Operationen steht im String nur "HALLO". Weder die Initialisierung funktioniert, noch das zweite Anhängen des Strings "BLUBB". Und wie gesagt, an anderen Stellen funktioniert dies absolut einwandfrei. Nur eben hier nicht.

EDIT: std::basic_string weist das selbe dämliche Verhalten auf.

Selbst das da funktioniert nicht:
Code:
string bla(string a, string b)
{
  // a und b sind hier entgegen (!) der übergebenen Parameter == "";
  return a + b;
}

void blubb()
{
  string ccc = "";
  ccc = "HALLO";
  ccc = bla(ccc, "TEST");
  // Herauskommen sollte eigentlich ccc == "HALLOTEST";
}

In der Funktion bla(string,string) sind beide Strings leer! Das ist ein völlig widersinniges Verhalten!

EDIT: Hammer! Nichtmal das funktioniert:
Code:
char bla[256];
strcpy(bla,"TEST");

selbst hier steht in bla nachher nichts drin. Wir probieren mal sprintf statt strcpy. Mal sehen...

edit: sprintf geht auch nicht! Ich dreh hier am Rad!

Code:
char bla[256];
sprintf(bla,"HALLO");

GEHT NICHT! *HEUL* *FLENN*

Code:
CString *honk = new CString("HALLO");

...geht auch nicht... *TILT* *resignier*


Wir sitzen da schon seit Stunden dran. Wir finden nix. Ich werd langsam depressiv.

:mad: :mad: :mad: :mad:

Gruß,
Hendrik
 
Zuletzt bearbeitet:
moin

string bla(string a, string b)
{
// a und b sind hier entgegen (!) der übergebenen Parameter == "";
return a + b;
}

void blubb()
{
string ccc = "";
ccc = "HALLO";
ccc = bla(ccc, "TEST");
// Herauskommen sollte eigentlich ccc == "HALLOTEST";
}

Mein Compiler sagt mir das das "return a + b;" nicht machbar ist.


mfg
umbrasaxum
 
Wie hast du den Inhalt überprüft. Im Debugger?

Ein Clean bzw. Rebuild all hast du sicher auch schon gemacht.

Dann solltest du die Funktion hier mal posten.
 
Mein Compiler meckert bei return a + b; nicht rum.
Rebuild wäre vielleicht nochmal 'ne Maßnahme, wird aber einige Zeit in Anspruch nehmen, weil das Programm doch ziemlich groß ist. 'ne viertel Stunde wird das wohl dauern.

Wir überprüfen den Inhalt im Debugger, ja, aber auch direkte Ausgaben funktionieren nicht. Also aufpoppen eines Dialogfeldes mit der Ausgabe, welche dann, wie zu erwarten war, leer ist.

Auf die Funktion hab ich persönlich gerade keinen Zugriff. Ich hol mir die gleich von 'nem Kollegen, pack sie dann hier noch rein. Der ist aber gerade eine rauchen... wie jedes Mal, wenn er gebraucht wird. :p

So, also die Funktion 1:1 kopiert... das meiste davon sind noch versuche, den String irgendwie übergeben zu bekommen. Alles vergebens. Teilweise funktioniert's, teilweise wieder nicht (s. Kommentare).
Code:
void CDlgFileTransfer::OnClose() 
{
	// Alle Update CGs rücksetzen und löschen 

	if (!m_UsedTransferCgs.IsEmpty()) // Läuft hier definitiv rein
	{
		string cmd;
		char yyy[256];
		int UsedCgCounter = m_UsedTransferCgs.GetTokenCount(';');
		for (int i = 0; i < UsedCgCounter;i++) // Läuft auch hier definitiv rein
		{

			String msg=""; // Okay, msg ist ""
			AfxFormatStrings(msg,String(ResId(IDS_STRING42049)),NULL,0); // Funktioniert auch

			string ccc = String(ResId(IDS_STRING42049)); // Funktioniert auch
			cmd = bla(cmd,"RESET CG:CG?="); // Funktioniert nicht!

			string aCgName = m_UsedTransferCgs.GetToken(i); // Funktioniert
			ccc = ccc + aCgName; // Funktioniert
			ccc = ccc + string(";"); // Funktioniert nicht

			cmd = bla(cmd,aCgName); // Funktioniert
			cmd = bla(cmd,string(";"));   // Funktioniert nicht
			CString xxx = "HALLO"; // Funktioniert nicht

			sprintf(yyy,"RESET CG:CG?="); // Funktioniert nicht
			sprintf(yyy, m_UsedTransferCgs.GetToken(i)); // Funktioniert nicht
			sprintf(yyy,";"); // Funktioniert nicht

			CString *honk = new CString("Hallo"); // Funktioniert nicht

			String bala = yyy; // Funktioniert nicht

			// Rest ist unwichtig

			CNode* pNode = CStation::GetStationByName(String(aCgName));


			fExecMML(cmd,0,0,0,0,MML_MASK_HIDDEN);

			if (pNode!=NULL){
				if (pNode->GetParent()->GetName()!="PUL") fExecMML("REMOVE CG:CG?=" + m_UsedTransferCgs.GetToken(i) + ";",0,0,0,0,MML_MASK_HIDDEN);
			}
		}
	}
	CISTSDialog::OnClose(); 

}
 
Zuletzt bearbeitet:
Lass zusätzlich den Assemblercode erstellen (Einstellungen C/C++ Listing Dateien) und überprüf in der entsprechenden Code Datei, was dort abläuft.
 
Also die Funktion wird aufgerufen, nachdem man in einem dazugehörigen Dialogfensters auf Close geklickt hat. Alle anderen Funktionen des Dialogfensters funktionieren einwandfrei.

Assemblercode ist so'ne Sache. Bin da nicht so bewandert... aber ich schau mal.

Wir machen jetzt 'n Rebuild. Hat zwar vorher auch nicht geholfen, aber dann fertigt er ein Assembler-Listing an. Vielleicht könnt ihr ja damit was anfangen:

Hier zum Beispiel mal 'n Ding das nicht funktioniert.

Code:
; 683  : 			CString xxx = "HALLO";

  04185	68 00 00 00 00	 push	 OFFSET FLAT:$SG92795
  0418a	8d 8d c0 fe ff
	ff		 lea	 ecx, DWORD PTR _xxx$92794[ebp]
  04190	e8 00 00 00 00	 call	 0CString@@QAE@PBD@Z	; CString::CString
  04195	c6 45 fc 12	 mov	 BYTE PTR __$EHRec$[ebp+8], 18 ; 00000012H

; 684  : 
; 685  : 			sprintf(yyy,"RESET CG:CG?=");

  04199	68 00 00 00 00	 push	 OFFSET FLAT:$SG92796
  0419e	8d 85 ec fe ff
	ff		 lea	 eax, DWORD PTR _yyy$92744[ebp]
  041a4	50		 push	 eax
  041a5	ff 15 00 00 00
	00		 call	 DWORD PTR __imp__sprintf
  041ab	83 c4 08	 add	 esp, 8

Was bedeutet das OFFSET FLAT:$SG92796 da? Ist das der Zeiger auf den an sprintf übergebenen Format-String?

Der Rest ist eigentlich nicht schwer. Es wird eax auf die Adresse des Character-Arrays geladen und quasi an die Funktion __imp__sprintf übergeben. Das müsste also theoretisch funktionieren.

Oder seh ich das falsch?

Selbst unser Ing. beißt sich daran die Zähne aus...
 
Ist vielleicht ein blöder Hinweis, aber habt ihrs mal so probiert?
CString xyz;
xyz = "hallo";

es funktioniert wirklich kein mal in dieser Funktion? Auch nicht
wenn ihr das direkt am Anfang der Funktion schreibt,also so:
Code:
void CDlgFileTransfer::OnClose() 
{
	// Alle Update CGs rücksetzen und löschen 
CString xyz = "xyz"; //bzw: CString xyz; xyz = "xyz";
	if (!m_UsedTransferCgs.IsEmpty()) // Läuft hier definitiv rein
	{
...
 
Ob es direkt am Anfang der Funktion geht, weiß ich so jetzt nicht, das haben wir noch nicht versucht. Aber was ich sagen kann, ist daß dein Konstrukt mit

CString xyz;
xyz = "Hallo";

auch nicht funktioniert.
 
Hi!

Was mir bei solchen Fehlern immer als erstes einfällt sind Speicherzugriffsverletzungen:
Das Programm schreibt in Bereiche, die nicht für das Programm freigegeben sind und dann treten (leider nur manchmal) an fehlerfreien Stellen Fehler auf..

Vielleicht prüft ihr euer Programm mal darauf. (gibt im Netz kostenlose Libs dafür.)

Gruß
Johannes
 

Neue Beiträge

Zurück