Problem mit Arrayspeicherung für VTK für meine Masterarbeit (richtige Version)
-
Hi Leute,
hier mein erster (bzw zweiter) Post nachdem beim ersten irgendwie einiges schief gegangen ist. Vorab sei gesagt, dass ich von Haus aus kein Programmierer bin sondern aus dem Bereich des Maschinenbaus komme und daher von (wahrscheinlich vielen) grundlegenden Dingen nicht sooo viel Ahnung habe.
Bin gegenwärtig dabei meine Masterarbeit zu schreiben und bin dadurch seit langer Zeit mal wieder mit C++ in Kontakt gekommen.
Vorab beschreibe ich kurz, was in der Arbeit gemacht wird und werde dann Teile des Quellcodes posten (darf leider nicht alles posten)
In meiner Arbeit simuliere ich mit einem in C++ umgesetzten Modell einen Beschichtungsprozess für Wärmedämmschichten.
Was passiert dabei?
Nunja es wird feines Pulver (meist aus Stahl oder Keramiken) in einem heissen Gasstrahl aufgeschmolzen und auf die zu beschichtende Oberfläche geschleudert. Direkt vor dem Aufprall haben die Partikel eine gewisse Geschwindigkeit und Temperatur sowie ihre Position relativ zur Oberfläche die als Eingangsdaten in den C++ Code eingelesen werdenWie sieht das im C++ Code aus?
Es wird ein 3D Array erstellt in dem dann nach und nach die einzelnen Partikel eintreten und das Array "auffüllen". Anschliessend werden diese Daten in jenem Array gespeichert. Es gibt in diesem Array also zwei Zustände.
1: Material in Form von aufgetragenen Partikeln vorhanden
2: kein Material vorhanden (s. Ergebnissdatei im Anhang = 0) Die 0 ist übrigens auch die Zahl der Oberfläche die wir beschichten.
Abschließend sollen diese Daten visualisiert werden um etwaige Hohlräume zwischen den Partikeln zu analysieren und das ist der Punkt wo es noch nicht so ganz rund läuft.
Hier will ich noch kurz erwähnen, dass dieses Modell vor 3 Jahren irgendwann mal grob implementiert wurde und meine Aufgabe ist es dieses zu verfeinern. Die "physikalischen" Verfeinerungen funktionieren aber bei der VTK Exportierung läuft noch was schief.
Und zwar entstehen bei der aktuellen Exportierung "komische" Zeichen in der Ergebnissdatei. Wir haben inzwischen ein Skript geschrieben mit dem man dieses Problem zwar nachträglich beheben kann aber es wäre halt schön wenn das direkt richtig funktionieren würde.
Hier zunächst mal der Quellcode der die VTK Datei erstellt.
Es funktioniert alles bis zu den 3 for Schleifen in denen das 3D Array "world" schrittweise durchlaufen wird.
//saving world's layers in one SMP_Results.vtk file FILE *file; const char* fileName="SMP_Results.vtk"; file=fopen(fileName,"w"); // char* text = "# vtk DataFile Version 2.0\nLayer Density 3D\nASCII\nDATASET STRUCTURED_POINTS\n"; char number[10]; //vtk header fputs("# vtk DataFile Version 2.0\nLayer Density 3D\nASCII\nDATASET STRUCTURED_POINTS\n",file); //DIMENSIONS y x z fputs("DIMENSIONS ",file); sprintf(number, "%d", sizeY); fputs(number, file); fputs(" ",file); sprintf(number, "%d", sizeX); fputs(number, file); fputs(" ",file); sprintf(number, "%d", sizeZ); fputs(number, file); fputs("\n",file); float yzKoef, xKoef; if(xDisc > yzDisc){ xKoef = 1; yzKoef = xDisc/yzDisc; } else { yzKoef = 1; xKoef = yzDisc/xDisc; } //ASPECT_RATIO yzKoef xKoef yzKoef fputs("ASPECT_RATIO ",file); sprintf(number, "%f", yzKoef); fputs(number, file); fputs(" ",file); sprintf(number, "%f", xKoef); fputs(number, file); fputs(" ",file); sprintf(number, "%f", yzKoef); fputs(number, file); fputs("\n",file); //ORIGIN 0 0 0 fputs("ORIGIN 0 0 0",file); fputs("\n",file); //POINT_DATA sizeY*sizeX*sizeZ fputs("POINT_DATA ",file); sprintf(number, "%d", sizeY*sizeX*sizeZ); fputs(number, file); fputs("\n",file); //SCALARS volume_scalars char 1 fputs("SCALARS volume_scalars char 1",file); fputs("\n",file); //LOOKUP_TABLE default fputs("LOOKUP_TABLE default",file); fputs("\n",file); char point[1]; char str[2*sizeY]; for(int k = 0; k < sizeZ; k++){ for(int i = 0; i < sizeX; i++){ for(int j = 0; j < sizeY; j++){ if(world[i][j][k] == 0) str[j*2] = '0'; else{ sprintf(point, "%d", world[i][j][k]); str[j*2] = point[0]; } str[j*2+1]= ' '; } fputs(str,file); fputs("\n",file); } fputs("\n",file); fputs("\n",file); fputs("\n",file); }
Ich komme nicht wirklich dahinter wie diese "Zeichen" entstehen. Mein betreuender Assistent sagte irgendwas mit "Adressbegrenzung des Arbeitsspeichers" oder so. Wir sind beide kiene Informatiker und sind irgendwie leicht überfragt.
Die Ergebnisdatei sind dann folgendermaßen aus:
# vtk DataFile Version 2.0 Layer Density 3D ASCII DATASET STRUCTURED_POINTS DIMENSIONS 1400 15 1400 ASPECT_RATIO 1.000000 1.000000 1.000000 ORIGIN 0 0 0 POINT_DATA 29400000 SCALARS volume_scalars char 1 LOOKUP_TABLE default 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ™ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ™ 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ™
Diese TM Zeichen sind uns ein Rätsel. Mein betreuender Assisten meinte was von Adressbegrenzung des Arbeitsspeichers? Aber der war sich auch nicht sicher. Sind beide leider keien Programmierprofis und daher hoffe ich auf eure Hilfe.
Vorab vielen Dank für Anregungen!
Viele Grüße
prX411
-
was ist world ? woher bezieht world seine daten ? wie sehen die urspruenglichen daten aus ?
bitte kuerze die daten am ende deines posts. bei mir wird dadurch die seite 2 meter breit
Meep Meep
-
Argh! Schön formatiert.
Ich denke den Mittelteil des Outputs hättest Du kürzen können...char point[1]; char str[2*sizeY]; for(int k = 0; k < sizeZ; k++){ for(int i = 0; i < sizeX; i++){ for(int j = 0; j < sizeY; j++){ if(world[i][j][k] == 0) str[j*2] = '0'; else{ sprintf(point, "%d", world[i][j][k]); str[j*2] = point[0]; } str[j*2+1]= ' '; } fputs(str,file); fputs("\n",file); } fputs("\n",file); fputs("\n",file); fputs("\n",file); }
- ist
str
immer ein string mit terminierenden null byte '\0'? Eher nicht. - ist
j*2+1
immer kleiner als2*sizeY
im Ausdruckstr[j*2+1]
? Eher nicht. point
ist einchar[1]
.sprintf(point, "%d", world[i][j][k]);
schreibt aber einenint
und ein terminierendes null byte. Passt das?
- ist
-
str[]
ist eins zu kurz.
char point[1]; sprintf(point, "%d",...
schreibt mindestens zwei Zeichen inpoint
->point
ist zu kurz.
Das ganze hat mit C++ nichts zu tun, das ist C.
Dein Beitrag ist um mehrere Bildschirmseiten zu breit (siehe Meep Meep), deine erste Version war wenigstens lesbar, das Layout benutzbar.
-
Da sind eine Menge WTFs (ein Paar auch mit undefiniertem Verhalten) im Code.
Dein unmittelbares Problem dürfte sein, dass str nicht terminiert wird, bevor in das File geschrieben wird.
for(int j = 0; j < sizeY; j++){ if(world[i][j][k] == 0) str[j*2] = '0'; else{ sprintf(point, "%d", world[i][j][k]); str[j*2] = point[0]; } str[j*2+1]= ' '; } str[sizeY*2-1]= '\0'; // <------------------ fputs(str,file);
Den Code richtig auseinandernehmen macht sicher noch jemand anderes.
...
wo ist der ABsendebutton hin
......
...
aha, auch ganz weit nach rechts gerutscht...
-
Dieser Thread wurde von Moderator/in SeppJ aus dem Forum C++ (auch C++0x und C++11) in das Forum C (C89, C99 und C11) verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
Danke erstmal für die schnellen Antworten.
Sorry für die 3 m breite Seite. Als ich es abgesendet hatte, klingelte das tele und ich hab erst gerade drauf geschaut
Wie gesagt, Teil des Codes stammt von einer älteren Diplomarbeit. Wir sind daraus leider nie schlau geworden...sind aber auch grauenhafte Anfänger
World ist das array in dem die Partikel bzw. die entstehende Schicht geschrieben wird.
Werde heute noch länger daran sitzen und mich öfter mal auf die hier erwähnten Probleme fokussieren. Hoffe ich kann damit reissen
Noch eine Frage: Was sagen die "TM" Zeichen denn genau aus ? Ein Datentyp wird "überlaufen" oder habe ich das falsch verstanden?
Danke erstmal!
-
Sei nicht so geizig mit dem Speicherplatz.
Wer VLA benutzt, so wie du, dem ist sowieso nicht mehr zu helfen und da ist dann alles egal.
Wennschon dannchar str[2+2*sizeY]; memset(str,0,2+2*sizeY);
Der letzte Zugriff
str[j*2+1]
ist dann kein UB mehr, weil du nicht mehr auf undefinierten Speicher zugreifst.
Hier wäre es auch einfacher, mit fwrite zu arbeiten, du brauchst dann keine '\0' Behandlung und keinen extra Speicher dafür (char str[**1+**2+2*sizeY])
fwrite(str,2+2*sizeY,1,file);
-
Wutz schrieb:
Sei nicht so geizig mit dem Speicherplatz.
Wer VLA benutzt, so wie du, dem ist sowieso nicht mehr zu helfen und da ist dann alles egal.Was ein Quatsch.
-
Erstens Quatsch, zweitens ist aus dem Code nicht ersichtlich, ob es sich um ein VLA handelt. Außerdem ist bei j < sizeY sichergestellt, dass 2 * j + 1 < 2 * sizeY, also ist die Arraygröße im Code des TE für den letzten Zugriff ausreichend. Und da das letzte Leerzeichen nicht gebraucht wird, kann man es wie camper durch einen Nullterminator ersetzen.
-
Hi Leute,
hatte die Tage keine Zeit aber wollte schnell Erfolg verkünden! Die "Zeichen" sind weg und es funktioniert, soweit bis jetzt getestet, jetzt alles wie geplant.
Die Zeile von Camper hats gerettetVielen vielen Dank und ich gelobe bei meinem nächsten Hilfeschrei Besserung hinsichtlich Formatierung
Gruß
prX