Zuweisung eines const wchar_t*
-
Du machst weisst da aber einem wchar_t einen Zeiger zu, was falsch ist.
Und dann musst du bei dieser Zuweisung darauf achten, dass du den Speicher nachher nicht mehr selbst freigibst, weil das dann einen Crash gibt. (ist undefiniert, aber mit grosser Wahrscheinlichkeit gibt es einen crash..)
Es ist einfach ein Mist, wenn du da dynamisch Verwalteten Speicher mit automatisch verwaltetem mischt. Das kommt bestimmt nicht gut.
-
Okay ...
Kannst du mir dann bitte sagen, wie ich rein dynamisch mir den Speicher dafür holen würde?
-
FrEEzE2046 schrieb:
Okay ...
Kannst du mir dann bitte sagen, wie ich rein dynamisch mir den Speicher dafür holen würde?
Das machst du doch bereits?
Ansonsten einfach genügend grossen Block Daten holen und dann z.B mit strcpy arbeiten.
-
Okay, sry, aber jetzt bin ich verwirrt^^.
drakon schrieb:
Du machst weisst da aber einem wchar_t einen Zeiger zu, was falsch ist.
Das verstehe ich nicht. Ich gehe davon aus, dass du diesen Teil meinst:
lpWinTitle = new const char[5];
Soweit ich weiß, ist *lpWinTitle der Zeiger und lpWinTitle der Inhalt ... richtig? Und ich brauche doch speicher für den Inhalt und nicht die vier Byte für den Zeiger?!
drakon schrieb:
Und dann musst du bei dieser Zuweisung darauf achten, dass du den Speicher nachher nicht mehr selbst freigibst, weil das dann einen Crash gibt. (ist undefiniert, aber mit grosser Wahrscheinlichkeit gibt es einen crash..)
Das verstehe ich auch nicht. Wenn ich mit new[] speicher hole, dann muss ich ihn doch auch wieder mit delete[] freigeben?!
Das meinte ich eben damit, wie ich denn dann dynamisch Speicher hole. Tut mir echt leid, wenn ich mich hier etwas blöd anstellen sollte, aber ich versuche das logisch nachzuvollziehen. Es muss doch eine Möglichkeit geben sich selber speicher zu allokieren, auf diesen einen Zeiger zu erhalten und anschließend den Speicher wieder freizugeben.
Und ich dachte, dass new[] genau das für ein Array tut ...
-
Ich habe mich auf das hier bezogen:
*lpWindowTitle = L"Form"; // Zuweisung der entsprechenden *lpNewWinTitle = L"myForm"; // Chars *ControlElement = L"button1";
Da hast du ersten den Compile Fehler drin. (Zuweisung von wchar_t* an wchar_t) und zweitens hast du ein Problem, weil der Zeiger, auf den Speicher, den du vorher angefordert hast verloren geht (mem Leak) und den neuen darfst du nicht freigeben, weil der automatisch verwaltet wird. (das L"Form" wird statisch gespeichert und von der Implementierung verwaltet).
-
Also müsste es so aussehen:
*lpWindowTitle = L"Form"; *lpNewWinTitle = L"myForm"; *ControlElement = L"button1";
Dann ist alos *lpWindowTitle der Inhalt und lpWindowTitle der Zeiger?
Das ich keinen Speicher allokieren und mir dann einfach neuen Speicher (durch die Zuweisung) besorgen lassen kann, leuchtet mir ein. Denn dann kann ich den Speicher nicht mehr freigeben.Dennoch erhalte ich auch bei oben genannten Code einen Fehler. Wie kann ich eine Zuweisung auf den Inhalt machen?
-
Du hast gleich mehrere Probleme.
lpWindowTitle = new const wchar_t[5];
Die const-Elemente des Arrays müssen initialisiert werden.
lpWindowTitle = new const wchar_t[5]();
*lpWindowTitle = L"Form";
lpWindowTitle ist ein Zeiger auf wchar_t, d.h. *lpWindowTitle könntest du natürlich nur ein wchar_t zuweisen.
*lpWindowTitle = L'F';
Soll die gesamte Zeichenkette kopiert werden brauchst du ein Funktion die dir die Zeichen an die durch lpWindowTitle bestimmte Stelle kopiert.
In deinem Fall funktioniert aber selbst
*lpWindowTitle = L'F';
nicht, weil du die Elemente des Arrays als const deklariert hast. Somit können sie auch nicht geändert werden.
FrEEzE2046 schrieb:
Dennoch erhalte ich auch bei oben genannten Code einen Fehler. Wie kann ich eine Zuweisung auf den Inhalt machen?
Vielleicht wird dir durch folgende Zeilen klar warum
*ControlElement = L"button1";
nicht geht. Wären es kein const-Elemente würde nämlich das gehen:
*ControlElement = L'b'; // oder alternativ ControlElement[0] = L'b'; //und weiter ControlElement[1] = L'u'; // ... ControlElement[6] = L'1'; ControlElement[7] = L'\0';
Oder, wie schon mehrfach bemerkt, mit einer Funktion, die dir die Zeichen kopiert. Einfach zuweisen geht so nicht.
-
Okay,
ich denke es jetzt verstanden zu haben.
Mein größtes Problem ist es hier irgendwie Zeiger und Inhalt nicht zu verwechseln.lpWindowTitle ist also der Zeiger und *lpWindowTitle der Inhalt.
Wenn ich mir folgendes Ausgeben lasse erhalte ich auch die entsprechenden Werte:lpWindowTitle = new wchar_t[5](); lpNewWinTitle = new wchar_t[7](); ControlElement = new wchar_t[8](); lpWindowTitle[0] = L'F'; lpWindowTitle[1] = L'o'; lpWindowTitle[2] = L'r'; lpWindowTitle[3] = L'm'; lpWindowTitle[4] = L'1'; lpWindowTitle[5] = L'\0'; lpNewWinTitle = lpWindowTitle; *ControlElement = L'button1'; cout << lpWindowTitle << "\t" << *lpWindowTitle << "\t" << lpWindowTitle[0] << endl; cout << lpNewWinTitle << "\t" << *lpNewWinTitle << endl;
Ausgabe:
02445348 70 70
024453448 70Dadurch ergeben sich mir mehrere Fragen:
1. Warum schreibe ich bei der Zuweisung lpWindowTitle[0] = L'F' kein * davor, wenn der Inhalt doch mit *lpWindowTitle erreicht wird?
2. Ist lpWindowTitle (wenn ich es mir ausgeben lasse) die Adresse zur Zeiger-Variablen oder die Adresse auf die die Zeiger-Variable zeigt?
3. Warum kann ich dann immer noch nicht mit delete [] lpWindowTitle den Speicher wieder freigeben?Das verstehe ich einfach nicht und daher kommen auch die anderen Fragen von oben zu stande.
Achso und noch etwas:
Brauche ich das hierwchar_t *lpWindowTitle = NULL;
überhaupt?
Das macht auf mich irgendwie auch schon wieder keinen Sinn. Ich sage *lpWindowTitle = NULL (also ein NULL-Pointer), aber ich denke jetzt, dass *lpWindowTitle der Inhalt ist und nicht der Zeiger.
Kann mir das bitte mal jemand erklären? Ich habe bereits in Büchern nachgeschlagen, aber auch dort ist mir das ganze nicht ersichtlicher geworden.
-
Uff! Sieht so aus als fehlen bei dir noch etwas die Grundlagen. Nachdem das unzählige Male erklärt wurde, werde zumindest ich nicht anfangen hier Zeiger zu erklären. Vielleicht hilft jemand aus, der etwas mehr in Schreiblaune ist.
Von mir zumindest ein Link:
http://www.highscore.de/cpp/einfuehrung/zeiger.htmlDann noch ein kleiner Ratschlag. Wenn du noch nicht genau verstanden hast wie das Zeug funktioniert, dann versuch doch es recht einfach zu halten. D.h. lass das const weg und verwende char statt wchar_t. Für wchar_t ist z.b. nicht cout vorgesehen sondern wcout, wcin, ...
Gibst du die wchar_t-Daten mit cout aus entstehen wieder Ungereimtheiten, wo keine sein müssten.FrEEzE2046 schrieb:
1. Warum schreibe ich bei der Zuweisung lpWindowTitle[0] = L'F' kein * davor, wenn der Inhalt doch mit *lpWindowTitle erreicht wird?
Der Compiler wandelt lpWindowTitle[0] um in *(lpWindowTitle + 0) entsprechend lpWindowTitle[1] in *(lpWindowTitle + 1) usw. ...
*Nur am Rande:
Wenn lpWindowTitle[0] in *(lpWindowTitle + 0) umgewandelt wird dann wird 0[lpWindowTitle] in (0 + lpWindowTitle) was ja nach Adam Riese dasselbe ist. Und, oh Wunder, es funktioniert auch mit 0[lpWindowTitle] oder 1[lpWindowTitle] oder 2[lpWindowTitle] ...FrEEzE2046 schrieb:
2. Ist lpWindowTitle (wenn ich es mir ausgeben lasse) die Adresse zur Zeiger-Variablen oder die Adresse auf die die Zeiger-Variable zeigt?
lpWindowTitle ist eine Variable die die Adresse eines wchar_t enthält
&lpWindowTitle wäre die Adresse der Variablen lpWindowTitle selbstDummerweise ist die Ausgabe von Zeigern auf char bzw. wchar_t mit cout bzw. wcout eine Besonderheit, da nicht der Inhalt der Zeigervariablen ausgegeben wird (also eine Speicheradresse) wie es bei Zeigern auf int, double, float, usw. der Fall wäre, sondern ein Interpretation des Inhalts der Speicheradresse als nullterminierte Zeichenkette.
int i=7; int *pi = &i; char *pc = "Hallo Welt"; //pc enhält danach die Adresse des ersten Zeichens 'H' cout << *pi << endl; // gibt 7 aus , wie erwartet cout << *pc << endl; //gibt 'H' aus, wie erwartet cout << pi << endl; //gibt den Inhalt von pi aus, also die Adresse der Variablen i, wie erwartet cout << pc << endl; //gibt "Hallo Welt" aus und nicht die Adresse des ersten Zeichens !!!
FrEEzE2046 schrieb:
3. Warum kann ich dann immer noch nicht mit delete [] lpWindowTitle den Speicher wieder freigeben?
Wenn lpWindowTitle noch immer auf den mit new [] angeforderten Speicher zeigt, also während des Programms NICHT irgendwie umgebogen wurde, z.B. auf ein Literal wie L"Hallo", ist delete[] kein Problem.
-
Naja, jetzt hast du es ja doch erklärt.
Eigentlich habe ich kein Problem mit Zeigern (in anderen Programmiersprachen), aber nur mit der Syntax hier in C++. Wenn der Compiler lpWindowTitle[0] in *(lpWindowTitle + 0) umwandelt, dann macht das Ganze auch seinen Sinn.
Es sah für mich nur so aus, als ob ich direkt lpWindowTitle (also die Speicheradresse) verändere und einen wchar_t zuweise, was keinen Sinn macht.