Kleine Zeigerfrage

HCWD

Erfahrenes Mitglied
Hi Ho Leute,

bin seid Neustem am C++ lernen und hab direkt mal ne Frage zu den Zeigern, da das aus dem Buch, das ich mir angelegt habe, nicht klar wird.

Nebeninfo: Java kann ich, somit würd ich auch das "hochgestochene Latinum" verstehen ;-)

Folgender Code-Fragment:

Code:
char szTmp[] = "Programmierung";
char *szText = new char[strlen(szTmp)+1];
strcpy(szText, szTmp);

printf(szTmp);

In der 1. Zeile deklariere ich einen Char-Array und Initialisieren dieses mit dem String "Programmierung"...

In der 2. Zeile deklariere ich nur einen Char-Arrayzeiger mit der Länge der szTmp + 1 als Größe...

In der 3. Zeile kopiere ich den Wert des kompletten Array szTmp in den Array szText?
Hier scheitert mein logisches Denken... Ich dachte eigentlich man müsste strcpy(szText, &szTmp) oder strcpy(*strText, szTmp) schreiben, weil entweder nutz ich mein szText als PointerArray oder ich nutze es als Zeiger auf einen Speicherbereich, um ihn dort abzuspeichern, den gegebenen Wert.

Kann mir dies jemand veranschaulicht erklären? Weil dieses Problem hat man bei Java nicht, da die ganze Zeigergeschichte im Hintergrund selbstgemanaged wird.
Höhstens bei den Objekten darf ich da bisschen Zeiger-technisch spielen, obwohl, da auch es sehr simplex strukturiert ist...
Nur bei C++ verliere ich da bissl den Überblick.

Würde mich sehr freuen, wenn mir jemand das erklären könnte...

Greetz

Euer HCWD^^
 
Moin,

char szTmp[] = "Programmierung";
Du initialisierst hier mit einem String-Literal, wodurch automatisch der entsprechende Speicher bereit gestellt wird! Zudem erfolgt dabei die "\0"-Terminierung!

strcpy(szText, szTmp);
Hier verbindest Du den Zeiger mit dem Speicherbereich Deines Zeichen-Arrays! Du könntest übrigens auch noch einfacher
Code:
szText = szTemp;
schreiben !

Da Du Dich aber schon mit C++ beschäftigst, würde ich Dir die Klasse "string" ans Herz legen, die um vieles flexibler und besser handhabbar ist! Das kommt der Logik, die Du von Java kennst, schon sehr viel näher :)

Gruß
Klaus
 
Hi.

Zu Zeile 2: du deklarierst einen Zeiger auf ein Zeichen. Diesen Zeiger initialisierst du mit der Adresse des Arrays welches du mit dem new[] Operator alloziert hast.

Arrays sind intern nichts weiter als Zeiger. Dieser Zeiger zeigt auf das erste Element des Arrays. Eine Arrayvariable in einem Zeiger-Kontext "zerfällt" automatisch in einen Zeiger auf das erste Element:
C++:
int array[55];

array == &array[0];
\edit: Man kann übrigens die Adresse einer Arrayvariablen nicht ermitteln. D.h.
C++:
&array == array
Deswegen ist diese Schreibweise unüblich.

Du mußt das Array dann wieder mit dem delete[] Operator freigeben.

Hier verbindest Du den Zeiger mit dem Speicherbereich Deines Zeichen-Arrays! Du könntest übrigens auch noch einfacher
Code:
szText = szTemp;
schreiben !
Das ist schlichtweg einfach nur falsch.

Gruß
 
Zuletzt bearbeitet:
Moin Deepthroat,

aha ... und warum funktioniert es dann ? ? ? ?
Hab's eben mal nachgelesen und auch schnell noch mal ausprobiert:
Code:
    char szTmp[] = "Programmierung-1";
    char *szTxt = new char[strlen(szTmp)+1];
    strcpy(szTxt, szTmp);

    char szTemp[] = "Programmierung-2";
    char *szText = new char[strlen(szTmp)+1];
    szText = szTemp;

Das klappt einwandfrei und wird auch hier in meinen div. SW an zig Stellen so verwendet .... :confused:

EDIT: es ist natürlich klar, dass ich im ersten Fall der Wert aus dem Speicherbereich von szTmp in den Speicherbereich von szTxt schreibe und im zweiten Fall einfach den Speicherbereich zuweise ... auf jeden habe ich szTxt/szText das Stringliteral stehen, was ich möchte und kann damit arbeiten ......

Gruß
Klaus
 
Zuletzt bearbeitet:
cool danke für die ausführlichen antworten...

jedoch hätte ich noch 2 fragen:

mit diesem strcpy(szText, szTmp) ist doch wie bei Java mit dem verknüpfen 2er Objekte gemeint oder wie? also wenn ich jetzt bei szText etwas abändern würde, würde es sich direkt auch auf szTmp auswirken?

das mit dem delete[] operator: ich hatte gelesen, wenn man ein "delete[] array" anwendet, ist das nicht zulässig, da die Begründung vom Prof. gefallen ist: "Statisch allokierter Speicher darf nicht gelöscht werden". also was mit statisch allokiertem Speicher gemeint ist, ist mir klar. Also hier ist der Speicher durch mich für nen Array deklariert worden, richtig?

und gelöscht ist doch das Freigeben des Array von einem bestimmten Speicherbereich gemeint? Nur wieso darf ich ihn net freigeben? Wenn ich einen Array nicht brauche, wieso darf ich ihn dann nicht für andere Zwecke wieder freigeben?

Greetz

hcwd
 
mit diesem strcpy(szText, szTmp) ist doch wie bei Java mit dem verknüpfen 2er Objekte gemeint oder wie? also wenn ich jetzt bei szText etwas abändern würde, würde es sich direkt auch auf szTmp auswirken?

Nein genau das nicht - siehe mein EDIT im letzten Post! Du weißt hier nur dem einen Speicherbereich den Wert, der im anderen steht zu!
Nur mit
Code:
szText = szTemp;
weisen beide Variablen auf dengleichen Speicher!

das mit dem delete[] operator: ich hatte gelesen, wenn man ein "delete[] array" anwendet, ist das nicht zulässig, da die Begründung vom Prof. gefallen ist: "Statisch allokierter Speicher darf nicht gelöscht werden". also was mit statisch allokiertem Speicher gemeint ist, ist mir klar. Also hier ist der Speicher durch mich für nen Array deklariert worden, richtig?

und gelöscht ist doch das Freigeben des Array von einem bestimmten Speicherbereich gemeint? Nur wieso darf ich ihn net freigeben? Wenn ich einen Array nicht brauche, wieso darf ich ihn dann nicht für andere Zwecke wieder freigeben?

Du darfst mit "delete" nur speicher freigeben, der zuvor mit "new" allokiert wurde ! !
Ein "delete szTmp" wäre fatal und wird auch nicht compliert, da der Compiler hier das "new" vermissen würde ...

EDIT: mit "new" allokierter Speicher heißt "dynamisch", da er ja erst zur Laufzeit allokiert, während die Größen des statischen Speichers (char cTest[10]) ja bereits zum Zeitpunkt der Compilierung bekannt ist !

Gruß
Klaus
 
Zuletzt bearbeitet:
Moin Deepthroat,

aha ... und warum funktioniert es dann ? ? ? ?
Hab's eben mal nachgelesen und auch schnell noch mal ausprobiert:
Code:
    char szTmp[] = "Programmierung-1";
    char *szTxt = new char[strlen(szTmp)+1];
    strcpy(szTxt, szTmp);

    char szTemp[] = "Programmierung-2";
    char *szText = new char[strlen(szTmp)+1];
    szText = szTemp;

Das klappt einwandfrei und wird auch hier in meinen div. SW an zig Stellen so verwendet .... :confused:
Deine Aussage war das strcpy(a, b) äquivalent ist zu einer Zuweisung a = b. Und das ist schlichtweg einfach falsch. Natürlich kannst du den Zeiger verändern und auf das Array zeigen lassen. Doch daraus resultiert in dem Fall ein Speicherleck.

Gruß

\edit @HCWD:
das mit dem delete[] operator: ich hatte gelesen, wenn man ein "delete[] array" anwendet, ist das nicht zulässig, da die Begründung vom Prof. gefallen ist: "Statisch allokierter Speicher darf nicht gelöscht werden". also was mit statisch allokiertem Speicher gemeint ist, ist mir klar. Also hier ist der Speicher durch mich für nen Array deklariert worden, richtig?
Mit der Aussage du mußt den Speicher von dem Array freigeben, meinte ich natürlich das dynamisch allozierte Array szText. Und du mußt dieses mit delete[] freigeben, nicht mit delete.
 
Zuletzt bearbeitet:
vfl_freak, Danke für die ausführliche Antwort... also dann ist mir das Ganze klarer geworden, weil auch aus der eigentlichen Beschreibung von strcpy dachte ich mir, dass man da ja nur einen Wert kopiert und nicht verknüpft...

Mir war halt nicht klar, ob ich nun den Zeiger (also die Adresse, an der ein bestimmter Wert liegt) oder den Wert selbst kopiere... Wobei es ja logischer ist, den Wert an dieser Stelle selbst zu kopieren, da das kaufmännische UND & ja nicht vor dem zweiten Operanden steht...

Also bei strcpy( operand 1, operand2) weiß ich also, dass da der Wert von Operand2 nach Operand1 kopiert wird...

Und bei strcpy(*operand1, operand2)? Ich mein, wenn ich versuche logisch da draran zu gehn, würd ich es so verstehen, dass wir einen Wert von Operand2 an den Speicherbereich von Operand1 kopieren... Was bewirkt dann dieser Stern? Weil beim Einen rufe ich doch den Operanden auf und beim Anderen rufe ich den Zeiger auf, der auf eine Speicherbereich verweist... Ist das nicht irgendwo der selbe Effekt?
 
Zuletzt bearbeitet:
Deine Aussage war das strcpy(a, b) äquivalent ist zu einer Zuweisung a = b. Und das ist schlichtweg einfach falsch. Natürlich kannst du den Zeiger verändern und auf das Array zeigen lassen. Doch daraus resultiert in dem Fall ein Speicherleck.

Ja, das hatte ich wohl unglücklich ausgedrückt und so nicht gemeint!
Na, ich hoffe, es ist jetzt klar geworden ...

Gruß
Klaus
 
also bei strcpy( operand 1, operand2) weiß ich also, dass da der wert von operand2 nach operand 1 kopiert wird...

und bei strcpy(*operand1, operand2)?
Das kommt ganz darauf an, was operand1 ist. Ausgehend von deinem Beispielcode würde das nicht kompiliert werden.

Gruß

PS: Bitte halte dich an die Netiquette, insbesondere Punkt 15. Danke!
 
Zurück