Zeigerproblem
-
Hallo,
weise ich folgender variable
unsigned char* ZDat1 = new unsigned char[5]; ZDat1[3] = 0x64;den Hex Wert 64 zu funktioniert alles wunderbar und die daten werden in einer späteren funktion in die Datei geschrieben. Der Wert 0x64 ist auch in der Datei.
nutze ich das gleich in einer schleife
for(int i = 0; i < 5; i++) { ZDat1[i] = Random(127); ShowMessage(IntToHex(ZDat1[i],2)); }Der Wert in der MessageBox wird richtig dargestellt jedoch in die Datei wird ein anderer Wert geschrieben den er irgendwo aus dem Speicher zieht aber nichts mit dem gewünschten Wert zu tun hat. In Meinem Fall schreibt er immer 0x12 egal was Random für einen Wert ausgibt.
In beiden Fällen wird ZDat1 an eine Variable unsigned char* Data aus einer Structur übergeben die es in einen Zwischenpuffer einsortiert und danach mit fstream speichert.
Leider bin ich am Ende meines Lateins und habe heute den ganzen Tag in den Büchern gewelzt und bin nicht einen Millimenter weitergekommen. Ich hoffe mir kann Jansen, Anteri oder ein Crack helfen.
danke
waldseeduo
-
Hallo,
also ich habe deinen Code mal getestet (mit random statt Random...) und er hat soweit funktioniert. habe mir den inhalt von ZDat1 in ein TMemo ausgegeben und die werte sind auch recht zufällig ( != 0x12 ).
mir scheint, dass dein fehler später auftaucht, aber wo, ist schwer zu sagen ohne quellcode
gruß, oli
-
hallo vatertagler,
Danke Oli für die Hilfe. Der Sourccode ist mehr das sind über 5000 Zeilen. ich kann sie dir gern mal schicken.
die Übergabe von ZDat erfolgt auf die untern aufgeführt Struktur auf den Wert Data.
SysexEvent Muster; Muster.Data = ZDat;Die Funktion an die die Struktur mit Muster.Data übergeben wird liegt in einer anderen Unit. Wie bereits gesagt gebe ich den reinen Hex Wert vor der Compal. durch funktioniert es. Greife ich auf Random oder eine andere von der Funktion erzeugten Integer zu macht er eine undefinierte Zahl.
typedef struct { unsigned long int TicksFromStart; unsigned long int TicksFromLastEvent; unsigned char Status; unsigned char HerstellerID; unsigned long int Eventlaenge; unsigned char* Data; } SysexEvent;so langsam dreh ich am rad wegen einer kleinigkeit jetzt den 2. Tag am suchen.
gruss
waldseeduo
-
hallo
hier ist der orginalcode
//Frames einfügen unsigned char* ZDat1 = new unsigned char[7]; ZDat1[6] = 0xF7; ZDat1[0] = a.HerstellerID; ZDat1[1] = 0x02 ; ZDat1[2] = 0x01 ; ZDat1[3] = 0x01 ; ZDat1[4] = 0x01 ; ZDat1[5] = 0x01 ; ZDat1[7] = '\0'; for(int i = 0; i < MaxTick; i = i + Framesabstand) { a.TicksFromStart = i; ZDat1[2] = 0x00 ; ZDat1[3] = 0x00 ; ZDat1[4] = 0x00 ; ZDat1[5] = 0x00 ; ZDat1[7] = '\0'; ZDat1[2] = random(127); a.Data = ZDat1; FHaupt->SMF1->AddSysex(a); }Nach meiner Vorstellung müsste ZDat1[2] einen Zufallswert enthalten jedoch wird immer der Wert 0x12 in die Datei geschrieben. Lass ich die Randomfunktion weg wird in die Datei 0x00 geschrieben.
Ändere ich den Wert ZDat1[2] = 0x03; Wird auch 0x03 in die Datei geschrieben.
danke
waldseeduo
-
Hi Waldseeduo,
soweit passt das doch wenn Du das random weg lässt schreibt er in die Datei doch genau das was Du erwartest.
Ich glaube Dein Problem ist das die random Funktion nicht so zufäälig ist wie man sich das erhofft.
Probier mal folgenden Code://randomize(); unsigned char Z; for (int i=0;i<10;i++){ Z=random(127); ShowMessage(Z); }Schau Dir dabei die Zahlen genau an. Dann beende das Programm und starte es neu.
Du wirst dann feststellen, das genau die Werte die Du beim ersten mal gesehen hast, wieder kommen.
Zur Verbesserung solltest Du das randomize() wieder "Einkommentieren".Gruß Alex
-
hallo alex,
leider nicht, ich habe auch schon die zählervariable aus der schleife genommen es kommt immer der gleich wert und der müsste wenigstens von 0 - x zählen und den wert übergeben.was ich nicht verstehe ist wenn ich ZDat einen wert zuweise ZDat1[2] = 0x20; Dann passt dass auch. Nur wenn zur Laufzeit auf ZDat1[2] ein Wert übergeben wird schüttelt er einen Wert der nirgends übergeben wurden. Üergebe ich zur Laufzeit 0x30 so erhalte ich z.B. 0x80
das macht ich stuzig. weise ich vor der laufzeit einen wert zu ist alles prima. mach ich es während der laufzeit gibt es probleme das die werte nicht stimmen.
-
Hi Waldseeduo,
tut mir leid das ich Dir nicht weiterhelfen konnte, aber ich verweise jetzt mal auf http://www.junix.ch/bcb/help debug das Programm bzw. die relevanten Teile doch mal step by step und schau Dir den Verlauf der Variable genau an, dann müßtest Du ja genau sehen, an welcher Stelle eine "falsche Zuweisug" ist, bzw wo Deine Variable verändert wird.Gruß Alex
-
hallo alex,
danke dir für die hilfe werde jetzt mal stück für stück durchhangelngruss
waldsee
-
1. Du erzeugst ein Arrey mit new ...
2. wo / wann gibst Du das frei???Falls Freigabe VOR schreiben in Datei erfolgt, ist das Verhalten nachvollziehbar.
-
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