paule22 Geschrieben 8. August 2002 Teilen Geschrieben 8. August 2002 Hallo Programmierer, ich hab da ein kleines Problem mit geschachtelten Strukturen. I habe folgende Strukturen: struct local_test_struct {  char *name;  int type;  struct local_test_struct *next; }; struct var_struct {  char *name;  int type;  struct local_test_struct *local_ptr;  struct var_struct *next; }; Die initial Struktur "var_struct" kann ich einwandfrei initializieren und damit arbeiten - arbeitet perfekt. Aber wenn ich "local_ptr" verwenden will bekomme ich immer einen Laufzeitfehler - Fehler in zuweisung - ACCESS VIOLATION Fehler. Ich benutze folgenden Code / Funktionen // Datei: xyz.cc typedef var_struct var_struct; var_struct *variablen_list; var_struct *variablen_list = (var_struct *) 0; var_struct *var_ptr; local_test_struct *add_local_variable(var_struct *proc_ptr, AnsiString name) {  local_test_struct *ptr;  ptr = new local_test_struct;  ptr->name = name;  ptr->next = (struct local_test_struct *) proc_ptr->local_ptr;  proc_ptr->local_ptr = ptr;  return ptr; } local_test_struct *get_local_variable(var_struct *proc_ptr, AnsiString name) {  local_test_struct *l_ptr;  for (l_ptr = proc_ptr->local_var;  l_ptr != (local_test_struct *) 0;  l_ptr = (local_test_struct *) l_ptr->next)  {  if (!strcmp(l_ptr->name,name))  return l_ptr;  }  return 0; } // und hier ist der Code, der mir ein paar kopfschmerzen sowie // einen Access Violation Laufzeitfehler bereitet... void handle(void) {  ...  // do other stuff mit var_struct  // z.b. init und add_variable("test");  ...  if (!var_ptr->local_var)  {  var_ptr->local_ptr = new local_test_struct;  var_ptr->local_prt->next = NULL;  }  local_test_struct *l_ptr;  if ((l_ptr = get_local_variable(var_ptr,str))) // diese Funktion bereitet mir kopfschmerzen  fatal("Variable bereits definiert."); } Was ist an der codierung so falsch ? schließlich funktioniert die folgende funktionen problemlos: var_struct *get_variable(char *name) {  var_struct *ptr;  for (ptr = variablen_list;  ptr != (var_struct *) 0;  ptr = (var_struct *) ptr->next)  if (!strcmp(ptr->name, name) return ptr;  return 0; } und die folgende funktion funktioniert auch einwandfrei ... var_struct *add_variable(char *name) {  var_struct *ptr;  ptr = new var_struct;  ptr->name = name;  ptr->next = (struct var_struct *)  variablen_list;  variablen_list = ptr;  return ptr; } hab mir einfach mal gedacht, den bereits existierenden Code (add_variable und get_variable) zu verwenden, um auf die Struktur innerhalb der Struktur zugreifen zu können (add_local_variable und get_local_variable) aber anscheinend geht das nicht so ohne weiteres - weis jemand weiter und wie ich das lösen kann ?? Vielen Dank für Rückantworten Paul Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 9. August 2002 Teilen Geschrieben 9. August 2002 Original geschrieben von paule22 local_test_struct *add_local_variable(var_struct *proc_ptr, AnsiString name) { Â local_test_struct *ptr; Â ptr = new local_test_struct; Â ptr->name = name; Â ptr->next = (struct local_test_struct *) proc_ptr->local_ptr; Â proc_ptr->local_ptr = ptr; Â return ptr; } Ich denke, das Problem liegt hier. Du weist dem char* ptr->name einen AnsiString zu. Das funktioniert vermutlich, weil diese Klasse einen cast-operator für diesen Typ hat. Das Problem ist, dass der AnsiString am Ende der Funktion zerstört wird, und ptr->name damit auf freigegebenen Speicher zeigt. Entweder muss die Struktur local_test_struct einen AnsiString statt eines char* enthalten, oder Du holst explizit Speicher für ptr->name in der entsprechenden Größe. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
paule22 Geschrieben 9. August 2002 Autor Teilen Geschrieben 9. August 2002 Hallo, hab ich trotz meiner bemühungen doch was übersehen. ptr->name ist im eigentlichen Code auch ein AnsiString, deshalb funzt des auch mit der zuweisung - nur hier im Forum dachte ich, lieber auf ANSI C umzustellen als auf Borland Code zurückzugreifen. Die folgende Funktion müsste dann so lauten: local_test_struct *add_local_variable(var_struct *proc_ptr, char *name) { local_test_struct *ptr; ptr = new local_test_struct; ptr->name = new char[strlen(name)]; strcpy(ptr->name,name); ptr->next = (struct local_test_struct *) proc_ptr->local_ptr; proc_ptr->local_ptr = ptr; return ptr; } funzt aber auch net so richtig irgendwas anderes muss das sein. Paul Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 9. August 2002 Teilen Geschrieben 9. August 2002 Original geschrieben von paule22 ptr->name = new char[strlen(name)]; Ist das jetzt wieder eine "umgestellte" Version? Wenn nicht, dann hast Du keinen Speicher für das Nullzeichen geholt. Wenn doch, dann gib uns besser den wirklichen Code. Ich denke, das erleichtert die Fehlersuche doch erheblich Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
paule22 Geschrieben 9. August 2002 Autor Teilen Geschrieben 9. August 2002 okay, hier ist der gesammte original code: die Struktur funktioniert - auch die AnsiString zuweisung außer was nicht funzt ist get_local_variable und evtl. dann auch add_local_variable .... hoffe du kannst was damit anfangen ... // File struct_def.h extern int fatal(AnsiString); // ---------------------------------------------------------------------------- // structure to store the variables that are defined by "local" ... // ---------------------------------------------------------------------------- struct __dbase_local_variables { AnsiString name; int type; double var_value; AnsiString var_string; bool var_bool; struct __dbase_local_variables *next; }; struct __dbase_variablen_struct { TObject *Sender; HWND Handle; bool Visible; int id; TdbWindowForm *t_form; TRAColorButton *t_button; TEdit *t_edit; AnsiString t_edit_text; AnsiString name; AnsiString parent; // for classes AnsiString proc_parent; // for procedures TColor fg_colornormal, fg_colorhighlight; TColor bg_colornormal, bg_colorhighlight; // hier die besagte struktur .... struct __dbase_local_variables *local_var; AnsiString proc_onclick; AnsiString proc_ongotfocus; AnsiString proc_onlostfocus; double var_value; AnsiString var_string; int push_count; int file_pos; int line_no; int type; struct __dbase_variablen_struct *next; }; typedef __dbase_variablen_struct __dbase_variablen_struct; extern __dbase_variablen_struct *__dbase_variablen_list; extern __dbase_variablen_struct *get_variable(AnsiString); extern __dbase_variablen_struct *add_variable(AnsiString); extern __dbase_variablen_struct *get_variable(HWND window); extern __dbase_variablen_struct *var_button_ptr; extern __dbase_variablen_struct *var_ptr; extern __dbase_local_variables *add_local_variable(__dbase_variablen_struct*, AnsiString); extern __dbase_local_variables *get_local_variable(__dbase_variablen_struct*, AnsiString); extern bool del_variable(AnsiString name); //File var_store.cc: #include "struct_def.h" // --------------------------------------------------------------------------- // 1. Typenzuweisung ... // --------------------------------------------------------------------------- __dbase_variablen_struct *__dbase_variablen_list = (__dbase_variablen_struct *) 0; __dbase_variablen_struct *var_ptr; // --------------------------------------------------------------------------- // prüfen, ob Variable in der Struktur vorhanden ist ... // --------------------------------------------------------------------------- __dbase_variablen_struct *get_variable(AnsiString name) { __dbase_variablen_struct *ptr; for (ptr = __dbase_variablen_list; ptr != (__dbase_variablen_struct *) 0; ptr = (__dbase_variablen_struct *) ptr->next) if (ptr->name == name) return ptr; return 0; } __dbase_variablen_struct *get_variable(HWND window) { __dbase_variablen_struct *ptr; for (ptr = __dbase_variablen_list; ptr != (__dbase_variablen_struct *) 0; ptr = (__dbase_variablen_struct *) ptr->next) if (ptr->Handle == window) return ptr; return 0; } __dbase_variablen_struct *add_variable(AnsiString name) { __dbase_variablen_struct *ptr; ptr = new __dbase_variablen_struct; ptr->name = name; ptr->next = (struct __dbase_variablen_struct *) __dbase_variablen_list; __dbase_variablen_list = ptr; return ptr; } __dbase_local_variables *add_local_variable(__dbase_variablen_struct *proc_ptr, AnsiString name) { __dbase_local_variables *ptr; ptr = new __dbase_local_variables; ptr->name = name; ptr->next = (struct __dbase_local_variables *) proc_ptr->local_var; proc_ptr->local_var = ptr; return ptr; } __dbase_local_variables *get_local_variable(__dbase_variablen_struct *proc_ptr, AnsiString name) { __dbase_local_variables *local_ptr; for (local_ptr = proc_ptr->local_var; local_ptr != (__dbase_local_variables *) 0; local_ptr = (__dbase_local_variables *) local_ptr->next) { if (local_ptr->name == name) return local_ptr; } return 0; } // ---------------------------------------------------------------------------- // deletes a stored variable by it's name ... // ---------------------------------------------------------------------------- bool del_variable(AnsiString name) { int index = 0; __dbase_variablen_struct *ptr; /* AnsiString str; str = "Durchlauf 1:\n"; for (ptr = __dbase_variablen_list, index = 0; ptr != (__dbase_variablen_struct *) 0; ptr = (__dbase_variablen_struct *) ptr->next, index++) { str += IntToStr(index) + ": " + ptr->name + ", next: "; if (ptr->next) str += ptr->next->name; else str += "NULL"; str += "\n"; } ShowMessage(str); */ for (ptr = __dbase_variablen_list, index = 0; ptr != (__dbase_variablen_struct *) 0; ptr = (__dbase_variablen_struct *) ptr->next, index++) { if (AnsiLowerCase(ptr->name) == AnsiLowerCase(name)) { // -------------------------------------------------------- // when der index = 0 ist, prüfen, ob hinter den index noch // daten sind, wenn ja, diese vorschieben ... // -------------------------------------------------------- if (index == 0) { __dbase_variablen_struct *save_ptr; save_ptr = ptr->next; delete ptr; __dbase_variablen_list = save_ptr; return true; } __dbase_variablen_struct *prev_ptr; int prev_index; for (prev_ptr = __dbase_variablen_list, prev_index = 0; prev_ptr != (__dbase_variablen_struct *) 0; prev_ptr = (__dbase_variablen_struct *) prev_ptr->next, prev_index++) { if (prev_index == index-1) { prev_ptr->next = ptr->next; delete ptr; return true; } } break; } } /* str = "Durchlauf 2:\n"; for (ptr = __dbase_variablen_list, index = 0; ptr != (__dbase_variablen_struct *) 0; ptr = (__dbase_variablen_struct *) ptr->next, index++) { str += IntToStr(index) + ": " + ptr->name + ", next: "; if (ptr->next) str += ptr->next->name; else str += "NULL"; str += "\n"; } ShowMessage(str); */ return false; } // File: start.cc #include "struct_def.h" void handle_file(AnsiString str) { // ------------------------------- // delete/erase var_ptr struct ... // ------------------------------- while (__dbase_variablen_list != NULL) { __dbase_variablen_struct *p = __dbase_variablen_list; __dbase_variablen_list = __dbase_variablen_list->next; delete p; } var_ptr = add_variable("start"); if (!var_ptr->local_var) { var_ptr->local_var = new __dbase_local_variables; var_ptr->local_var->next = NULL; } __dbase_local_variables *local_ptr; // hier ist die mackenhafte function if ((local_ptr = get_local_variable(var_ptr,str))) fatal("LOCAL Variable bereits definiert."); ShowMessage("add"); // und diese Funktion macht evtl. auch dann mackken ... local_ptr = add_local_variable(var_ptr,str); } irgend wo weiter im code: handle_file("begin"); handle_file("start"); Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 9. August 2002 Teilen Geschrieben 9. August 2002 Ich habe in Deinem Code keine Stelle gefunden, an der local_var mit Null initialisiert wird. Innerhalb von add_variable wäre es angebracht. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
paule22 Geschrieben 9. August 2002 Autor Teilen Geschrieben 9. August 2002 jo hast recht, das war das Problem !!! Ich dachte immer, daß, wenn eine Struktur im Speicher initializiert wird alle Items auf NULL gesetzt werden. Anscheinend nicht Ist eigentlich blöd das man das von hand nachträglich abändern muss. Aber in gewisser Hinsicht logisch. Der Speicher wird ständig beschrieben -> ständig neues Zeug. danke für deine Hilfe !!! Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.