Wie verkettete Listen mit beliebigen Struct-Zeigern

calgonite

Grünschnabel
Vielen Dank, dass Du meinen Beitrag liest :rolleyes:

Ich versuche folgendes zu verwirklichen: eine einfach verkettete Liste mit dem Inhalt: ein Zeiger, der auf eine (beliebige von mir früher definierte Struct zeigt). Jetzt gibt es eine ganze Reihe von Strukturen (effectpara1FX .. effectparaNFX) mit unterschiedlicher Struktur. Wenn ich jetzt die Liste erstelle, die ja nur aus der Zeiger-Struct besteht (s.u.) , möchte ich dem Zeiger in der UNIT einen Zeiger auf eine (beliebeige) meiner verschiedenen Stucts zuweisen. Der Compiler will aber nicht einen Zeiger in einen anderen verwandeln (Pointer ungleich Pointer). Wie kann ich das lösen?


typedef struct listenUNIT
{

struct listenUNIT *pnext;
struct listenUNIT *effectpara;

} UNIT;


typedef struct effectpara1FX
{

float fpara1;
float fpara2;
int ipara1;
int ipara2;
} FX;


typedef struct effectpara2FX
{

float fpara1;
int ipara1;
} FX;


UNIT *pstart;
UNIT *pstore;
UNIT sonic;

FX *pfxstore;

pfxstore = (FX *)malloc(200);

pstart = &sonic;
sonic.effectpara = pfxstore;
// hier fehler

free(pfxstore);


Ich will also eine beliebig lange Liste erzeugen, die Pointer auf beliebige Structs aus meinen vordefinierten Structs zeigt. :eek:

Chris.
 
Da gibt es für C und C++ unterschiedliche Lösungen.
C: Du musst die Pointer alle auf den gleichen Typ casten, um sie in den Container zu packen. Um beim Herausholen den Typ feststellen zu können, benötigen die verwendeten Typ eine übereinstimmende Eigenschaft, die den Typ kennzeichnet, damit du passend zurückcasten kannst.
Code:
struct unknown
{
  int type; // wird zur Typkennzeichnung  verwendet
};

struct typ1
{
  int type; // wird zur Typkennzeichnung  verwendet

  ///.. weitere Eigenschaften
};

struct typ2
{
  int type; // wird zur Typkennzeichnung  verwendet

  ///.. weitere Eigenschaften
};

#define TYP_UNKNOWN (0)
#define TYP_TYP1 (1)
#define TYP_TYP2 (2)
Wenn du nun zum Beispiel ein Typ1-struct erzeugst, musst du den Typ korrekt setzen, bevor du das Ding in die Liste hängst. Beim Auslesen kann dann anhand der Typeigenschaft korrekt zurückgecastet werden.
C++:
Hier gibt es zwei Ansätze.
1. Der erste ist dem obigen Ansatz ähnlich. Deine Datentypen sind von einer Basisklasse abgeleitet. Der Container (hier würde ich dann auch eher eine STL-Liste verwenden) enthält Basisklassenzeiger, die dann entweder (unschön) auf den korrekten Typ zurückgecastet werden, oder du definierst in der Basisklasse schon ein für alle Typen ausreichendes Interface, dass an den entsprechenden Stellen von den Kindklassen überschrieben bzw. überhaupt erst implementiert wird. Stichworte: Vererbung, Polymorphismus.
2. Du verwendest eine Klasse, die beliebige Datentypen kapseln kann, zum Beipiel boost::any, und packst diese in einen Container.
 
Zuletzt bearbeitet:
danke ich werde mal nachsehen

Okay, merci erstmal. Ich muss wohl oder übel mich mehr mit Klassen und Vererbung beschäftigen.

Chris :-)
 
Okay, merci erstmal. Ich muss wohl oder übel mich mehr mit Klassen und Vererbung beschäftigen.
Das hängt natürlich davon ab, ob du das in C oder in C++ machen willst.
In C++ ist das natürlich eleganter lösbar durch Ableitung.

Gruß Homer
 
noch einfacher..

Aber noch einfacher wäre das:

Ich brauche eine Methode, mit der man den Pointer auf einen anderen schreiben kann ohne dass der Compiler testet auf WAS der pointer zeigt.

Geht das? Mit asm? Habe bisher nur ASM auf dem AMIGA gemacht vor ungefähr 15 Jahren :-)


Chris
 
Weiterer versuch

Ich hab es probiert, aber der Compiler hat Probleme, mit dem auf die einen struct definiertem Zeiger auf eine andere struct zuzugreifen:

typedef struct fx1
{
float zahl;
unsigned short calgon;
} axa1;

typedef struct fx2
{
char b;
int calgonit;

} axa2;

fx1 effect1;
fx2 effect2;
fx1 *zeiger1;
fx2 *zeiger2;
effect1.zahl = 9.2f;
effect2.b = 22;
zeiger1 = &effect1;
zeiger2 = &effect2;

zeiger1 = reinterpret_cast<fx1*>(zeiger2);

printf("zahl %f \n \n", effect1.zahl);
//printf("zahl %f \n \n", zeiger1->zahl); // das geht

printf("zahl %f \n \n", zeiger1->b);
// geht nicht, obwohl zeiger1 jetzt auf die effect2 also die fx2 struct zeigt
// der Compiler sagt: 'b' : is not a member of 'fx1'

Wie kann man das umgehen? Ich möchte, dass man den zeiger auf effect1 in einen zeiger auf effect2 umwandelt und dann auch die Elemente von effect2 ansprechen zu können.

Chris
 
Code:
printf("zahl %f \n \n", zeiger1->b);

natürlich geht das nicht , du benutz ein axa1 Zeiger ! axa1 enthält kein element b. Auch nicht dann wenn durch ein cast eigentlich auf die Axa2 struktur zeigst !

du könntest natürlich mit char* auf die einzelnen Bytes von Axa2 zugreifen , aber dann musst du dir die Floats wieder myhsam zambasteln
 
du könntest natürlich mit char* auf die einzelnen Bytes von Axa2 zugreifen , aber dann musst du dir die Floats wieder myhsam zambasteln
Davon kann ich nur abraten. Das würde nicht richtig funktionieren und zu einer Brutstätte für Fehler werden.

@calgonite: Kannst du mal erklären, was du mit der Pointerumwandlung beabsichtigst? Vielleicht kann ich dir weiterhelfen.
 
wfür brauche ich das?

Stellt Euch vor, ihr habt viele verschiedene Structs, z.B Effect-Parameter. Erst in Runtime wird ein script ausgelesen, in dem z.B ein effect von den vielen aufgerufen wird. (und in die Liste mit den laufenden effekten eingetragen wird) Ein "Effekt" (funktion) kann auch mehrmals aufgerufen werden, braucht aber dann jeweils einen eigenen Speicherbereich (die Struct), um laufende Parameter abzuspeichern.

Also brauche ich eine verkettete Liste, deren Inhalt ein pointer auf eine (beliebige struct), Hinzu kommt noch ein wert, der besagt, auf welchen typ struct ich zeige.

Aber ich löse das jetzt anders, bisher komme ich gut voran. :p

Chris
 
Unbedingt C?

Musst du das unbedingt in ANSI C machen?
Oder kannst du auch auf C++ ausweichen?
(ausweichen :-) klingt wie eine Notlösung, soll es aber auf keinem Fall sein).
Denn in C++ könntest du dir eine Effekte Basisklasse definieren und einen Container bzw. verkettet Liste der/die dann Zeiger auf die Basisklasse aufnimmt.
Diese Zeiger kannst du dann dank Polymorphie auf die abgeleiteten Effektklassen casten.
Das nur mal so als Vorschlag.

Gruß Homer
 
Zurück