Zeigerproblem
-
hallo,
ich gebe es überhaupt nicht frei im augenblick.verstehst du unter freigabe "delete ZDat1;"
leider bin ich ein wenig verwirrt mit dem debuggen da sind schon wieder andere werte als in die datei geschrieben wird.
so langsam dreh ich echt am rad.danke
waldseeduo
-
Mir ist gerade noch so aufgefallen, dass du dies machst.
unsigned char* ZDat1 = new unsigned char[7]; //... ZDat1[7] = '\0';Das ist in keinem Fall eine gute Idee (Index zu groß). Vielleicht bringt eine Verbesserung hier was?
Gruß, Oli
-
waldsee schrieb:
hallo,
ich gebe es überhaupt nicht frei im augenblick.Das ist nicht gut!!!
waldsee schrieb:
verstehst du unter freigabe "delete ZDat1;"
Ja
waldsee schrieb:
leider bin ich ein wenig verwirrt mit dem debuggen da sind schon wieder andere werte als in die datei geschrieben wird.
so langsam dreh ich echt am rad.Das Verhalten deutet darauf hin, dass Du auf Daten im Speicher zugreifst, deren Adresse ungueltig / falsch ist!!!
Machst Du das new ... mehrmals???
Verlierst Du irgendwo den Zeiger???Was passiert nach new ... und der Eingabe der Daten bis zum schreiben der Daten in Datei mit dem Zeiger?
-
http://www.mira-multimedia.de/ablage/source.jpg
hier ist ein screenshoot. ich habe die funktion abgespeckt. die werte im debugger.
die zählervariable hat den wert 7
ich weis auch nicht warum die werte nicht stimmen von qwe.data
gruss
waldsee
-
http://www.mira-multimedia.de/ablage/source2.jpg
Das bild hat eine Zählervariablenstand von 7 und trozdem ist Data im Debugger Leer!
Hier habe ich noch das gleiche nur dass ich die zählervariable an dqe.Data übergebe.
dqe ist die in den ersten postings aufgeführte struktur hier hat sieht data so aus.
unsigned char* Data;
-
In deinem Screenshot ist das char-Feld immer noch nur 7 Zeichen groß, du greifst aber auf 8 Feldelemente zu in deiner for-Schleife! --> gar nicht gut

Oli
-
Ts, Ts, Ts ....
1. Du erzeugst INNERHALB einer Funktion ein Temporaeres Array (Stack)
2. Du fuellst das mit Werten (Naja)3. Wo schreibst Du die Datei? In einer ANDEREN Funktion!!! Oder nicht?
Wenn ja: Dein Datenfeld ist mit verlassen der Funktion UNGUELTIG. D.h. bei erstbester Gelegenheit werden die Daten da im RAM ueberschrieben!!!- Du verlierst den Zeiger auf das Feld -

3. qwe.Data=""; erzeugt eine Referenz auf einen String der Laenge Null!!! dhinter ist kein RAM reserviert!
4. qwe.Data[s] greift damit HINTER Deine (leere) Stringvariable!!!
Das kann nicht gut gehen!!!
-
Wieso ist das Array temporär? Es wird mit new erzeugt, d.h. dynamisch und müsste doch auf dem dynamischen Speicher, dem Heap, abgelegt werden! Insofern müsste der Speicher auch außerhalb der Funktion zugreifbar sein.

Oli
-
Aber die (Zeiger-) Variable ist im Stack!!!
Damit wird der Zeiger ungueltig UND im Heap bleibt ein LOCH!
-
hi,
unsigned char* ZDat1 = new unsigned char[8]; for(int s = 0; s < 8; s++) { ZDat1[s] = s; } delete ZDat1;warum bleibt bei ZDat1 immer der Wert "" also kein Inhalt. Normal müsste doch nach dem schleifendurchlauf ZDat1[0] = 0, ZDat1[1] = 1 usw haben oder sehe ich da was falsch.
ich versuche stück für stück einzugrenzen und alles nicht benötigte mal wegzulassen. bitte altenburger schlage nicht die hände über dem kopf ich habe mir alles selbst beigebracht ich hab niemals nur eine edv stunde erhalten ich kann nur aus fehlern lernen und was ich in meinen büchern finde.
doch im augenblick ist schucht im schacht und morgen geht der 3 tag an dem ich an ein paar zeilen rumhacke und nicht einen millimeter vorwärts komme das ist frustrierend.

danke
-
DerAltenburger schrieb:
Aber die (Zeiger-) Variable ist im Stack!!!
Damit wird der Zeiger ungueltig UND im Heap bleibt ein LOCH!
Und damit ist dein Problem gefunden! (Danke Altenburger für die lehrreiche Lektion.)
waldsee schrieb:
for(int s = 0; s < 8; s++) { ZDat1[s] = s; }Leider weist du hier nicht Zahlen sondern ASCII-Codes zu und 0 bis 7 sind keine druckbaren Zeichen.
Probier's mal mit
[cpp]for(int s = 0; s < 8; s++)
{
ZDat1[s] = s + 48;
}
[/cpp]
dann siehst du auch die Zahlen.Zur Lösung deines Problem musst du dein char-Feld also außerhalb der Funktion und zwar in der rufenden Funktion anlegen. D.h. du musst für deine Struct Speicher reservieren, den du dann auch mit Hilfe andere Funktionen füllen kannst. Alles klar?

Du schaffst das!
Oli
-
ob ich das schaffe weis ich nicht. ich werde es auf jeden fall selbst versuchen wollen. ich werde auf alle fälle bescheid geben ob es klappt oder nicht.
aus fehlern wird man schlau. dann hab ich noch ne menge fehler vor mir

danke oli und altenburger
-
Bitte auch beachten:
Wenn Speicher mit
new[...]geholt wird, muss er auch mit
delete[]gelöscht werden.
Gruß Nighthero
-
Nochmal hierzu:
DerAltenburger schrieb:
Aber die (Zeiger-) Variable ist im Stack!!!
Damit wird der Zeiger ungueltig UND im Heap bleibt ein LOCH!
Habe folgenden Code erfolgreich getestet (Ausgaben als Kommentar):
void dosth(char*& pt) { char msg[64]; char* ch = new char[10]; for(int i=0; i<10; ++i) ch[i] = i+48; Memo1->Lines->Add(ch); // 0123456789 sprintf(msg,"Adresse: %p", ch); // Adresse: 008E3F9C Memo1->Lines->Add(msg); pt = ch; // Adresse des dynamisch erstellten Speicherbereichs // an übergebenen Parameter zuweisen sprintf(msg,"Adresse: %p", pt); // Adresse: 008E3F9C Memo1->Lines->Add(msg); } void func() { char msg[64]; char* ptr = 0; dosth(ptr); Memo1->Lines->Add(ptr); // 0123456789 sprintf(msg,"Adresse: %p", ptr); // Adresse: 008E3F9C !!! Memo1->Lines->Add(msg); delete[] ptr; // !!!!!!!!!!!!!!!!!!! }D.h. bei Übergabe einer Referenz des char ptr* nimmt er die Adresse auch an. Definiere ich den Funktionskopf allerdings so:
void dosth(char* pt);funktioniert es nicht. Ist der Grund die Übergabe einer Kopie?
Jedenfalls, waldsee, kannst du entsprechend einfach eine Referenz (keinen Zeiger) auf deine Struct übergeben und müsstest entsprechend die dynamisch erzeugten Werte zuweisen können. Das wäre ein minimaler Änderungsaufwand

Oli
-
im augenblick versteh ich nur bahnhof, es muss irgendwo in der übergabe bei mir scheitern. ich muss aber jetzt erst mal ein wenig meinen kopf sammeln das war zuviel die letzten tage für meine rübe oder sollte ich es mal mit alohol versuchen wenn ich die leute heut gesehen habe bin ich mir sicher das ein grosser teil die heut unterwegs waren keine probleme mit einem zeiger haben

Das einzigste Zeigerproblem wird der Zeiger im Wecker sein der morgen früh bimmelt
waldsee
-
char* ch = new char[10];was ich jetzt aber nicht ganz verstehe ist warum du in der funktion dosth nicht delete ch; brauchst?
-
weil du ja sonst den dynamisch zugewiesenen speicher, der auf dem heap angelegt wird und auf den ich mit dem Zeiger ptr in func() zugreifen will, wieder freigeben würdest!!! dann würdest du wiederum mit ptr ins Leere greifen.
So richtig sauber ist diese Lösung allerdings nicht, da man leicht den Überblick über angelegten und freigegebenen Speicher verlieren kann...
gruß oli
-
kann ich eine array das ich mit new erzeugt hab in einer anderen funtion zerstören z.B. nachdem es gespeichert wurde oder muss dies immer in einer funktion geschehen?
-
ja, du kannst den speicher auch in einer anderen funktion freigeben, wie ich es im beispiel angegeben habe.
der speicher im heap existiert ja solange, bis du delete bzw. delete[] aufrufst oder das programm beendet wird. wenn du also einen zeiger auf den speicherbereich im heap hast, kanns du den dynamischen speicher dort abräumen.
oli
-
wenn ich aus einer anderen funktion versuche aufzuheben
delete[] ZDat1;erhalte ich immer undefiniertes Symbol als Fehlermeldung da es auserhalb des Bereiches liegt.
waldsee