Mailinglist Archive: opensuse-programming-de (140 mails)

< Previous Next >
Re: Konvertierung von unsigned char* auf signed char*
  • From: Michael Matz <matz@xxxxxxx>
  • Date: Thu, 10 Oct 2002 15:09:01 +0200 (CEST)
  • Message-id: <Pine.LNX.4.33.0210101451580.9652-100000@xxxxxxxxxxxxx>
Hi,

On Thu, 10 Oct 2002, Christian Weickhmann wrote:

> Das ist vielleicht nicht so ganz rübergekommen (OK, ich habe es ja nicht
> richtig hingeschrieben...): Genau dieser Typecast führt zu Müll!

Kann nicht sein ;-) Gib einen vollstaendigen Sourcecode (aber bitte <
100 Zeilen), der dies tut.

> unsigned char* irgendwas = "Blablabla";
> strcpy(zielString, (const char*)irgendwas);
>
> aufrufe steht da Müll!

Ist "zielString" denn nun alloziert oder nicht?

> Beim Ausdrucken fällt das erst richtig auf:
>
> unsigned char* irgendwas = "Blabla";
> printf("%s", irgendwas); // Funktioniert hier interessanterweise
> // ohne &

Klar. &irgendwas haette ja Typ "unsigned char **" (die Addresse eines
Pointers hat eben Typ Pointer of Pointer), und das wuerde sicherlich,
wenn interpretiert als String ("%s"), lustige Hexzeichen ausgeben.

> printf("%s", (char*)irgendwas);

Das funktioniert definitiv so. Wenn es das nicht tat, dann war entweder
"irgendwas" nicht initialisiert, oder du hattest nicht genau die obige
Zeile geschrieben.

> Ich kann's leider nicht reproduzieren, weil ich die Stelle
> im Code bereits geändert habe. Jedenfalls kommt bei einem
> Typecast eben nicht der richtige Inhalt raus...

Doch.

> Klasse sm_schueler speichert die Daten einer Person (eines Schülers)
> und stellt Funktionen zu deren Manipulation bereit.
> Will ich jetzt ein Array von solchen Objekten erzeugen, kann es dann
> der Grund für dieses SIGSEGV sein, dass ich folgendes gemacht habe:
>
> sm_schueler *s[100]; // um 100 Elemente von sm_schueler zu initialisieren...

Ehm. Das initialisiert ueberhaupt nix. Du scheinst verwirrt zu sein
bezueglich Objektinstanzen und Pointer auf Objektinstanzen. Obiges
reserviert Speicher fuer 100 _Pointer_ auf sm_schueler Instanzen. Wenn es
ne globale Var ist, dann sind alle diese Pointer nach Programmstart
NULL-initialisert, wenn's ne lokale Variable ist, steht einfach Muell drin
(liegt eben auf dem Stack).

> dann der Aufruf:
>
> s[0]->setName("EinName");

Hast du jemals s[0] irgendwas zugewiesen, wie z.B. "s[0]=new sm_schueler;"
Wenn nicht, dann ist s[0] immer noch 0, womit wir also effektiv den Aufruf
0->setName(...) haben, was natuerlich ebenfalls ne SEGV produziert, da der
this pointer dann NULL ist.

> Ist das so korrekt oder muss ich s[0] vorher noch initialisieren? Wenn ja,
> wie?

Naja, du musst eben Instanzen dieser sm_schueler Klasse anlegen, du hast
ja explizit bloss pointer darauf reserviert. Wenn du gleich beim
Programmstart den Speicher fuer diese Instanzen reservieren willst (im
Gegensatz dynamisch zur Laufzeit), so musst du s so schreiben:

sm_schueler s[100];

Das reserviert 100 Instanzen von sm_schueler, und 0-initialisiert sie
(wenn s file-global ist). Aufrufe von Methoden auf diesen Objekten nutzen
dann natuerlich nicht den -> operator, sondern:

s[0].setName(...);

Man beachte, das dann s[0] eben nicht mehr die _Addresse_ eines Objektes
ist, sondern das Objekt selbst. Die Address von ihm ist &s[0].


Ciao,
Micha.


< Previous Next >