problem bei speicherreservierung
-
Fachmann schrieb:
naja ok ich bau ma through,catch,try exeptions ein.
Das kannst du gerne tun, aber das hilft dir bei diesem Problem nicht.
-
Wie sieht denn nun die Schleife aus? Und wie hoch ist vertices?
-
schleifenkopf:
for (i = 0; i < header.frames; i++)frames = 10
vertices = 24
joar und beim ersten schleifendurchgang ist i=0.
dh1. durchgang:
frame[0].vertex = new CMD2Vertex[24];aber das ist alles irrelevant denn:
frame[i].vertex = NULL;...gibt auch ein fehler
-
Mehr Code.
-
aber das ist alles irrelevant denn:
frame[i].vertex = NULL;...gibt auch ein fehler
Das heißt, dass es NICHT am allokieren liegt - sondern daran:
frame[i].vertexVersuch mal das davor zu schreiben:
frame[0]; //bzw frame[i]Ich wette, dass es schon da den Zugriffsfehler gibt...
Du machst also vor der Schleife schon irgendwas 'komisches' mit dem Objekt, weil all das, was du gepostet hast nicht der fehler ist ^^ also geh doch ma punkt für punkt den quellcode durch und guck immer, welche adresse und inhalte 'frame[0]' denn hat...
Debugger sind schon toll... :p
-
mmh hier nochmal alles auf einen schlag:
struct CMD2Vertex { float x,y,z; }; ... struct CMD2Frame { CMD2Vector3 scale; CMD2Vector3 translate; char name[16]; CMD2Vertex *vertex; }; ... class CMD2Model { public: CMD2Frame *frame; int frames; ... }; bool CMD2Model::Load(...) { ... frames = header.frames; frame = new CMD2Frame[header.frames]; printf("header.frames: %d",header.frames); //Ausgabe: header.frames: 10 printf("\nheader.vertices: %d",header.vertices); //ausgabe: header.v = 24 for (i = 0; i < header.frames; i++) { printf("i=%d",i); frame[i].vertex = NULL; //Error ... } ... }so, frame wurde nicht richtig allokiert oder so aber warum? bei den anderen speichern ging es doch auch und die sehen auch so aus
-
Kann es sein, dass dein CMD2Model nicht richtig erstellt wurde bzw. schon wieder gelöscht wurde, wie unskilled schon geschrieben hat? Setz mal Breakpoints im Kon- und Destruktor, und überprüf, dass die Adresse des Objektes stimmt.
-
ich hab den this zeiger im konstructor und in der load-methode abgerufen:
zwei unterschiedliche werte.
hier wird die classe deklariert (keine argumente an konstruktor) und die load-methode gestartet:CMD2Model model2;
if(model2.Load("C:\\animation.md2","",GL_LINEAR)==false)
puts("\n ERROR loading MD2");
-
Dann finde doch mal mit deinem Debugger raus, wo sich genau die Addresse deines Objektes ändert.
-
untersuche den Inhalt von frame unmittelbar vor der Zuweisung, die die beschriebene Ausnahme erzeugt.
Unhandled exception at 0x004019b8 in main.exe: 0xC0000005: Access violation writing location 0x00000029.
Diese Ausnahmen haben nichts mit C++-Exceptions zu tun. Diesem Fehler zufolge, wird ein Schreibzugriff auf die Adresse 41 versucht - falls tatsächlich die obige Zuweisung die betreffende Stelle ist, kann das eigentlich nur an einem fehlerhaften Wert in frame liegen (allerdings wohl nicht genau 0, denn vertex als Zeiger müsste eigentlich entsprechend (wohl auf 4 Byte) ausgerichtet sein). Letzlich kann dir nur der Debugger mehr verraten. Eine fehlgeschlagene Speicherreservierung kann dafür allerdings nicht verantwortlich sein, denn dann würde die Programmausführung diesen Punkt nie erreichen (weil eine echte C++-Exception vom Typ std::bad_alloc (oder davon abgleitet) geworfen würde).
-
der debugger sagt:
bei dem "vertex" objekt in der struct "Frame"
Error CXX0017 : symbol "" not found
gegooglet, rumprobiert, hab noch nicht gescheites dadrüber gesehen
komisch find ich das:
wenn ich in der klasse stattCMD2Frame *frame;schreibe, eine richtige array deklarier:
CMD2Frame frame[20];dann sieht der debugger kein error mehr beim object "vertex" aber der altbekannte error "unhandled exeption" kommt immernoch

-
boar ey...
jz schreib doch einfach mal nen bissl quellcode hier her...bye!
-
was soll ich den schreiben?? das problem ist doch nur. ich reserviert speicher für eine structure. den bereich kann ich aber nicht ansprechen:
hier das ganze: (*.h)struct CMD2Vector3 { float p[3]; }; typedef struct CMD2Vertex { float x; float y; float z; }; struct CMD2TexCoord { short s; short t; }; struct CMD2Skin { char name[64]; }; struct CMD2Triangle { unsigned short vertex[3]; unsigned short st[3]; }; struct CMD2Frame { CMD2Vector3 scale; CMD2Vector3 translate; char name[16]; CMD2Vertex *vertex; }; struct CMd2Header { int ident; int version; int skinwidth; int skinheight; int framesize; int skins; int vertices; int st; int triangles; int glcmds; int frames; int offset_skins; int offset_st; int offset_tris; int offset_frames; int offset_glcmds; int offset_end; }; class CMD2Model { public: CMD2Triangle *triangle; int triangles; int skins; CMD2Skin *skin; int texcoords; CMD2TexCoord *texcoord; CTga tex; char *tex_filename; CMD2Frame *frame; int frames; char *filename; //// CMD2Model(); bool Load(char *arg_md2_filename,char *arg_texture_filename, unsigned int arg_tex_flag); ~CMD2Model(); }; #endifund hier *.cpp datei...
bool CMD2Model::Load(char *arg_md2_filename, char *arg_texture_filename, unsigned int arg_tex_flag) { int i=0; filename = (char*) malloc(strlen(arg_md2_filename)+1); tex_filename = (char*) malloc(strlen(arg_texture_filename)+1); strcpy(filename,arg_md2_filename); strcpy(tex_filename, arg_texture_filename); printf("\n%s",arg_md2_filename); FILE* f_md2; f_md2 = fopen(arg_md2_filename,"rb"); if(f_md2 == NULL) return false; CMd2Header header; fread(&header,1,sizeof(header),f_md2); if ((header.ident != 844121161) || (header.version != 8)) return false; triangles = header.triangles; triangle = new CMD2Triangle [triangles]; skins =header.skins; skin = new CMD2Skin [skins]; frames = header.frames; ///hier wird frame allokiert://///////////////////////////// frame = new CMD2Frame[header.frames]; ////////////////////////////////////////////////////////////// printf("header.frames: %d",header.frames); texcoords = header.st; texcoord = new CMD2TexCoord[texcoords]; fseek (f_md2, header.offset_skins, SEEK_SET); fread (&skin, sizeof (struct CMD2Skin),skins, f_md2); fseek (f_md2, header.offset_st, SEEK_SET); fread (&texcoord, sizeof (CMD2TexCoord),texcoords, f_md2); fseek (f_md2, header.offset_tris, SEEK_SET); fread (&triangle, sizeof (CMD2Triangle),triangles, f_md2); fseek (f_md2, header.offset_frames, SEEK_SET); printf("\nheader.vertices: %d",header.vertices); for (int i = 0; i < 10; i++) { printf("i=%d",i); /////hier gibts denn error://///////////////////////////////// printf("%s",frame[i].vertex); ////////////////////////////////////////////////////////// //frame[i].vertex = new CMD2Vertex[header.vertices]; fread (&frame[i].scale, sizeof (CMD2Vector3), 1, f_md2);puts("OKl"); fread (&frame[i].translate, sizeof (CMD2Vector3), 1, f_md2);puts("OKl"); fread (&frame[i].name, sizeof (char), 16, f_md2);puts("OKl"); fread (&frame[i].vertex, sizeof (CMD2Vertex),header.vertices, f_md2);puts("OKl"); } fclose (f_md2); return true; }
-
also - wenn du das ganze so lassen willst, dann solltest du im C forum posten - das ist ALLES c - kein stück C++... ok - die news sind C++ ^^
fread (&skin, sizeof (struct CMD2Skin),skins, f_md2); //falsch?! => fread (&skin, sizeof (CMD2Skin),skins, f_md2); UND: guck dir ma streams an... std::istream datei; //vll auch ostream ^^ weiß ich nicht, weil ich verwends niemals ^^ datei.open (".\\dateiname.endung"); // gleiches verzeichnis datei >> skins; // skins aus datei auslesen...so rum is natürlich nicht all zu intelligent...
printf("%s",frame[i].vertex); frame[i].vertex = new CMD2Vertex[header.vertices]; => frame[i].vertex = new CMD2Vertex[header.vertices]; std::cout << frame[i].vertex[0] << std::endl; //#include <iostream>btw: wenn du new verwendest, solltest du auch delete verwenden... sonst is bissl doof, wenn du nur speicher anforderst und nie freigibst...
filename = (char*) malloc(strlen(arg_md2_filename)+1); tex_filename = (char*) malloc(strlen(arg_texture_filename)+1); => char *r = new char [laenge+1]; oder noch besser: std::string var ("beliebiger inhalt................................");bye...
PS: ich seh kein stück durch da... man kann auch fkt und klassen schreiben in c++. das macht es zumindest nicht verworrener - nur leserlicher, logischer, .... - besser eben ; )
-
mh das ist doch eine class "CMD2Model"
das prinzip ist, die Klasse CMD2Model soll eine md2-datei (3d-model-datei, mit animation) laden.
dazu werden die ganzen strukturen erstellt (zb CMD2Texture)
in der CMD2Model-Klasse werden dann zeiger auf die strukturen deklariert.
nun wird der header der datei gelesen.
daraus wird entnommen wieviel Vertices, Frames, Skins, usw in der Datei sind.
Dementsprechend wird der Platz reserviert:... triangle = new CMD2Triangle [triangles]; skins =header.skins; skin = new CMD2Skin [skins]; ...nun werden die daten in die reservierten speicher geladen:
... fseek (f_md2, header.offset_st, SEEK_SET); fread (&texcoord, sizeof (CMD2TexCoord),texcoords, f_md2); ...für jedes frame wird nun ein schleifendurchgang vorgenommen in dem platz für die vertices in einem frame einen speicherplatz reserviert bekommen und die daten in diesen platz geschrieben werden.
bei der allokaliesierung (oder so) von "frame" gibt es vermutlich einen fehler, sodass nicht zugegriffen wernden kann. aber warum?(this-zeiger ist immmer gleich)
ich hab mir gedacht, wenn es da ein fehler bei der allokalisierung von frames gibt, dann schaff ich das einfach ab. sprich: ich leg eine array für die ganzen frames fest:
CMD2Frame frame[20];
und schreib dann in der schleife darein die frame-daten
in der Hoffnung dass der Fehler nichtmehr vorkommt.
aber er kommt trotzdem
warum kommt dieser scheiss fehler? der pisst mich an. son scheiss hat ich noch nieps: class = c++ , new = c++,
der rest ist c weil ich das jetz mal übersichtlicher fand. für ein amateur reichts, solang es keine fehler verursacht, zumindest keine fatalen
-
wenn es übersichtlich wäre, dann würdest du den fehler finden...
#include <string> #include <fstream> #include <iostream> bool CMD2Model::Load(const std::string &arg_md2_filename, const std::string &arg_texture_filename, size_t arg_tex_flag) { filename, tex_filename; //als std::string deklarieren (dafür brauchste nen #include <string>) //strcpy ist eh deprecated... guckst du msdn... das aktuelle sollte strcpy_s sein filename = arg_md2_filename; //mit strings geht das so schön einfach, wahrscheinlich fast genau so schnell, sicherer, komfortabler und vor allem nicht so fehleranfällig tex_filename = arg_texture_filename; std::cout << arg_md2_filename << std::endl; //ausgabe.... std::ifstream f_md2; //#include <ifstream> if (!f_md2.open (arg_md2_filename)) return false; CMd2Header header; f_md2 >> header; if ((header.ident != 844121161) || (header.version != 8)) //was auch immer ^^ return false; triangles = header.triangles; //was auch immer - ich nehm mal an size_t //vll solltest du das auch triangle_count nennen - ist übersichtlicher und deutlicher... triangle = new CMD2Triangle [triangles]; //typ wirst du scho wissen und wird scho stimmen... skins = header.skins; //den sinn hiervon seh ich auch gerad nicht... skin = new CMD2Skin [header.skins]; frames = header.frames; frame = new CMD2Frame [header.frames]; std::cout << "header.frames: " << header.frames << std::endl; texcoords = header.st; texcoord = new CMD2TexCoord [texcoords]; f_md2.seekg (header.offset_skins, std::ios::beg); f_md2 >> skin; //die beiden zeilen könnte man auch in ne fkt zusammen packen... /* so in etwa: template <T> void readout (ifstream &dateistream, T &ausgabe, size_t offsetwert) { dateistream.seekg (offsetwert, std::ios::beg); dateistream >> ausgabe; } */ //usw... std::cout << "header.vertices: " << header.vertices << std::endl; for (size_t i (0); i < 10; ++i) { std::cout << "i= " << i << std::endl; frame[i].vertex = new CMD2Vertex [header.vertices]; std::cout << frame[i].vertex << std::endl; ifstream >> frame[i].scale; std::cout >> "\tOK1" >> std::endl; ifstream >> frame[i].translate; std::cout >> "\tOK2" >> std::endl; ifstream >> frame[i].name; std::cout >> "\tOK3" >> std::endl; ifstream >> frame[i].vertex; std::cout >> "\tOK4" >> std::endl; } return true; }guck dir das mal an - sind bestimmt noch 1 oder 2 fehler drin - aber versuchs ma so weit zu ändern und sag, was dann passiert...
-
ok hat ein bisschen gedauert weil noch weitere, andere probleme entstanden sind aber hier nun der code:
typedef struct C3DVertex { float x,y,z,u,v; }C3DVertex;un hier das sorgenkind:
C3DVertex *vertex =NULL; vertex = new C3DVertex[head.num_vertices]; int vi = 0; for(i=0;i<pModel->nNumMeshes;i++) { for(int j=0; j<pModel->pMeshes[i].nNumVertices;i++) { MBFLAG /// MESSAGEWINDOW vertex[vi+j].x = pModel->pMeshes[i].pVertices[j].Vertex[0]; vertex[vi+j].y = pModel->pMeshes[i].pVertices[j].Vertex[1]; vertex[vi+j].z = pModel->pMeshes[i].pVertices[j].Vertex[2]; vertex[vi+j].u = pModel->pMeshes[i].pVertices[j].u; vertex[vi+j].v = pModel->pMeshes[i].pVertices[j].v; MBFLAGS //// MESSAGEWINDOW mit S } vi = j+1; }nun gibt es einen runtime-error nachdem MBFLAG 3x aufgerufen wurde. sprich: der error entsteht im 2. durchgang der schleife.
das ist allerdings nur so wenn head.num_vertices==2.
wenn head.num_vertices größer ist dann durchläuft es mehrer durchgänge bis zum error.
dass der RAM voll ist glaub ich aber wohl kaum. das kann nicht sein