Zum Inhalt springen

Empfohlene Beiträge

Geschrieben

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

Geschrieben
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.

Geschrieben

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

Geschrieben
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 ;)
Geschrieben

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");

Geschrieben

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 !!!

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.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...