Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   [C++] Pointer-Problem: illegal indirection (https://www.delphipraxis.net/102976-%5Bc-%5D-pointer-problem-illegal-indirection.html)

Matze 7. Nov 2007 19:23


[C++] Pointer-Problem: illegal indirection
 
Hallo zusammen,

mein C++-Compilier (VS2005 Prof.) meldet mir "illegal indirection" bei diesem Code:

Code:
void CKommunikation::StudentenInfo(void)
{
   CStudent *studentenliste;
   studentenliste = pa.StudentenlisteSenden();

   for (int i = 0; i < 8; i++)
   {
      cout << "Name: " << *studentenliste[i].NameSenden() << ", Matrikel-Nr.: " << *studentenliste[i].MatrikelNrSenden() << "\n";
   }
}
Das MSDN sagt dazu folgendes:

Zitat:

Compilerfehler C2100

Fehlermeldung
Zeigeroperation ungültig
illegal indirection

Der Dereferenzierungsoperator (* ) wurde mit einem Wert verwendet, der kein Zeiger ist.
Nur finde ich keinen Fehler.

StudentenlisteSenden sieht wie folgt aus:

Code:
CStudent * CPruefungsamt::StudentenlisteSenden()
{
   return arrStudenten;
}
und arrStudenten ist ein Array aus mehreren Instanzen der Klasse CStudent:

Code:
CStudent arrStudenten[8];
Was mache ich falsch?

Grüße

hoika 7. Nov 2007 19:34

Re: [C++] Pointer-Problem: illegal indirection
 
Hallo,

ich würde mal ein paar Variablen verwenden
und dann den Debugger nehmen.

Delphi-Quellcode:
void CKommunikation::StudentenInfo(void)
{
   arrayStudent *studentenliste;
   CStundent ???
   studentenliste = pa.StudentenlisteSenden();

   for (int i = 0; i < 8; i++)
   {
      CStudent = studentenliste[i];
      cout << "Name: " << CStudent.NameSenden() << ", Matrikel-Nr.: " << CStudent
.MatrikelNrSenden() << "\n";
   }
}

Heiko

Matze 7. Nov 2007 19:38

Re: [C++] Pointer-Problem: illegal indirection
 
Hallo Heiko!

Zitat:

Zitat von hoika
ich würde mal ein paar Variablen verwenden

Was meinst du damit?

Zitat:

Zitat von hoika
Code:
void CKommunikation::StudentenInfo(void)
{
   arrayStudent *studentenliste;
   CStundent ???
   // ...

Da die Studentenliste ein Array der Instanzen von CStudent ist, muss ich als "Datentyp" schon den Klassennamen CStudent angeben.

Grüße

Torpedo 7. Nov 2007 19:43

Re: [C++] Pointer-Problem: illegal indirection
 
*studentenliste[i].NameSenden()
Wenn das ein Array ist kannst du den * wahrscheinlich weglassen, da Arrays Pointer sind.

Khabarakh 7. Nov 2007 19:45

Re: [C++] Pointer-Problem: illegal indirection
 
Der bislang völlig von C++ Verschonte wagt eine Antwort, mal sehen, was daraus wird :stupid: . Jedenfalls dürfte in C++ wie in C#[*] gelten, dass "*" als unärer Operator einen niedrigeren Rang als "." als primärer Operator einnimmt. Solange du also nicht den Rückgabewert der Methode dereferenzieren willst, musst du klammern oder "->" verwenden.
Zitat:

postfix-expression . name
postfix-expression –> name


Remarks
The member access operators . and -> are used to refer to members of structures, unions, and classes. Member access expressions have the value and type of the selected member.

There are two forms of member access expressions:

In the first form, postfix-expression represents a value of struct, class, or union type, and name names a member of the specified structure, union, or class. The value of the operation is that of name and is an l-value if postfix-expression is an l-value.

In the second form, postfix-expression represents a pointer to a structure, union, or class, and name names a member of the specified structure, union, or class. The value is that of name and is an l-value. The –> operator dereferences the pointer. Therefore, the expressions e–>member and (*e).member (where e represents a pointer) yield identical results (except when the operators –> or * are overloaded).
[*] Bitte daraus nicht schließen, dass man in c# solche Ungeheuer öfter als zweimal pro Dekade bräuchte ^^ .

PS: Dass der Compiler den nicht-passenden Typen überhaupt nicht beim Namen nennen, könnte man ja fast als blanken Hohn ansehen... aber mit seinen knapp 30 Jahren kann man das der Sprache wohl noch verzeihen ;) .

[edit]
@Torpedo: So wie ich mein Zitat verstanden habe, kann der .-Operator nur nach dem Dereferenzieren der Klasse benutzt werden - sonst wäre sein "->"-Kumpane ja völlig witzlos.
[/edit]

Matze 7. Nov 2007 19:47

Re: [C++] Pointer-Problem: illegal indirection
 
Hallo

Zitat:

Zitat von Torpedo
Wenn das ein Array ist kannst du den * wahrscheinlich weglassen, da Arrays Pointer sind.

Da ich aber auf den Inhalt des Arrays zugreifen möchte, brauche ich doch diesen Inhaltsoperator (oder wie sich der nennt). Oder nicht?

Lasse ich das weg, erhalte ich diese Fehler:

Zitat:

Error 1 error LNK2001: unresolved external symbol "public: int __thiscall CPruefung::NummerSenden(void)" (?NummerSenden@CPruefung@@QAEHXZ) CKommunikation.obj
Error 2 fatal error LNK1120: 1 unresolved externals D:\Eigene Dateien\...\Projekt_1.exe 1
Ob sie allerdings damit zusammenhängen, weiß ich nicht, denke aber schon. :?

Edit: @Sebastian: Danke, doch damit geht's irgendwie auch nicht. Frustrationshalber habe ich alle Kombinationan ausprobiert: Mit * und ->, ohne Stern und -> etc. *g* Aber alles hilft nicht.

Torpedo 7. Nov 2007 19:48

Re: [C++] Pointer-Problem: illegal indirection
 
Zitat:

Zitat von Matze
Da ich aber auf den Inhalt des Arrays zugreifen möchte, brauche ich doch diesen Inhaltsoperator (oder wie sich der nennt). Oder nicht?

Auf den Inhalt greifst du dann doch mit dem []-Operator zu ;)
Vielleicht hat auch Khabarakh recht, probiers mal aus.

EDIT:
So wie ich das verstehe greifst du mit dem zusätzlichen * auf das 1. Element im Array zu. Da dieses Element aber kein Array ist, kann dann nicht mit [i] auf dessen Elemente zugegriffen werden. Ich weiß aber nicht ob * oder [] einen höheren Stellenwert hat, also kann auch umgekehrt sein.

Khabarakh 7. Nov 2007 20:01

Re: [C++] Pointer-Problem: illegal indirection
 
Zitat:

Zitat von Torpedo
Ich weiß aber nicht ob * oder [] einen höheren Stellenwert hat, also kann auch umgekehrt sein.

[] ist ebenfalls primär.
Wir wollen also folgende Reihenfolge erreichen:
  1. Array indexieren (ja, das Wort gibt's laut LEO wirklich :mrgreen: ) per [] primär
  2. Zeiger auf Klasse dereferenzieren per * unär
  3. Memberzugriff per . primär
=> Entweder Klammer um 2. oder 2.+3. durch "->" zusammenfassen.

Matze 7. Nov 2007 20:14

Re: [C++] Pointer-Problem: illegal indirection
 
Moin,

danke für die Mühe, aber irgendwie bin ich zu blöd dafür. *g*

Ich habe ja den Pointer aufs 1. Arrayelement. Damit ich direkt das Array nutzen kann, muss ich das doch dereferenzieren mittels * und dann müsste ich's doch normal nutzen können. Daher hätte ich es der Überlegung nach so gemacht:

Code:
(*studentenliste)[i].NameSenden()
Aber das geht auch nicht. Wo sollen deiner Meinung nach denn die Klammern hin?

Torpedo 7. Nov 2007 20:14

Re: [C++] Pointer-Problem: illegal indirection
 
Liste der Anhänge anzeigen (Anzahl: 1)
Delphi-Quellcode:
cout << "Name: " << studentenliste[i].NameSenden() << ", Matrikel-Nr.: " << studentenliste[i].MatrikelNrSenden() << "\n";
Bei mir funktionierts so.

Habe es mal kurz nachprogrammiert (Achtung, Klassen abgeändert)
Im Anhang habe ich den Quellcode. Getestet mit g++.

Ausgabe:
Zitat:

Name: Max Mustermann, Matrikel-Nr.: 1234
Name: Max Mustermann, Matrikel-Nr.: 1234
Name: Max Mustermann, Matrikel-Nr.: 1234
Name: Max Mustermann, Matrikel-Nr.: 1234
Name: Max Mustermann, Matrikel-Nr.: 1234
Name: Max Mustermann, Matrikel-Nr.: 1234
Name: Max Mustermann, Matrikel-Nr.: 1234
Name: Max Mustermann, Matrikel-Nr.: 1234

Apollonius 7. Nov 2007 20:17

Re: [C++] Pointer-Problem: illegal indirection
 
Auch wenn ich nicht sehr oft mit C++ gearbeitet habe, würde ich intuitiv doch Torpedo zustimmen. Denn wenn ich einen int* habe, diesen als Array interpretiere und dann indexiere (und das gibts :shock: ), dann muss ich das nicht auch noch dereferenzieren. Zum Mitschreiben:
Code:
int* IntArray;
IntArray = new int[5]; //ist das so richtig?
//oder gerne auch mit malloc

IntArray[3] = 5;

delete IntArray;
Und jetzt lyncht mich.

Torpedo 7. Nov 2007 20:24

Re: [C++] Pointer-Problem: illegal indirection
 
@Apollonius:
Das ist mehr Java als C++ ;)

Hier mal ein Beispiel:
Code:
#include <iostream>
using namespace std;

int main() {
   int arr[5];      // Normales Array erstellen
   int * a = arr; // Das Programm kompiliert hier fehlerlos, weil ein array ein Pointer ist und damit mit int* kompatibel
   a[0] = 3; // Trotzdem kann man dann ohne * darauf zugreifen, weil das schon [] macht
   cout<<a[0]<<"\n"; // Es wird 3 ausgegeben
   return 0;
}

Matze 7. Nov 2007 20:26

Re: [C++] Pointer-Problem: illegal indirection
 
Tatsache, Torpedo hat recht. :thumb:

Der Fehler:

Zitat:

Error 1 error LNK2001: unresolved external symbol "public: int __thiscall CPruefung::NummerSenden(void)" (?NummerSenden@CPruefung@@QAEHXZ) CKommunikation.obj
Error 2 fatal error LNK1120: 1 unresolved externals D:\Eigene Dateien\...\Projekt_1.exe 1
trat auf, weil ich hier das "void" als "Parameter" vergessen hatte. :wall:

Code:
void CPruefung::NummerSenden()
Ich danke allen, die mir hier geantwortet haben. :)

Khabarakh 7. Nov 2007 20:27

Re: [C++] Pointer-Problem: illegal indirection
 
Aaaah, jetzt hab ich es auch verstanden. Glaube ich :mrgreen: . Wenn ich das richtig sehe, enthält das Array ja gar keine Zeiger, sondern direkt die Objekte (so langsam verstehe ich, warum C++ mit diesem Konzept ziemlich allein auf weiter Flur steht *g*), dann ist die Dereferenzierung per * oder -> natürlich komplett überflüssig. Die Dereferenzierung von CStudent* nach CStudent steckt ja schon im []-Operator.

[edit]
Jut, so langsam erreichen wir wohl Konsens ;) .
[/edit]

Apollonius 7. Nov 2007 20:28

Re: [C++] Pointer-Problem: illegal indirection
 
@Torpedo:
Das ist wohl ein Kompliment - ich habe mich nie im Entferntesten mit Java beschäftigt.
Aber sofern mich meine C-Kenntnisse nicht ganz verlassen haben, ist mein Code auch halbwegs korrekt, wenn ich ein dynamisches Array erstellen will - bei dir ist die Größe ja hartcodiert. Und falls das new nicht ganz stimmen sollte, kann man ja auch malloc(5*4) nehmen.

Matze 7. Nov 2007 20:37

Re: [C++] Pointer-Problem: illegal indirection
 
Zitat:

Zitat von Khabarakh
Aaaah, jetzt hab ich es auch verstanden. Glaube ich :mrgreen: [...] Die Dereferenzierung von CStudent* nach CStudent steckt ja schon im []-Operator.

Ach jetzt verstehe ich's auch so langsam. :mrgreen: Das hat Torpedo ja eigentlich auch geschrieben, nur war ich fest davon überzeugt, dass ich das manuell mit dem * machen muss. :angle2:

Nun habe ich hier 2 nützliche Dinge gelernt:

1. [] ist ein Operator (ich wusste das wirklich nicht)
2. [] dereferenziert gleich, sehr schön. :)

Danke nochmals.

OregonGhost 7. Nov 2007 21:04

Re: [C++] Pointer-Problem: illegal indirection
 
Etwas offtopic, aber vielleicht interessant für dich:
Zitat:

1. [] ist ein Operator (ich wusste das wirklich nicht)
Dann zieh dich schonmal warm an. Der Pfeil ->, die Klammern (), das Komma , , das Und &, der Punkt . usw. sind auch alle Operatoren. Aber das kranke daran ist, dass man sie (fast) alle überladen kann. Viel Spaß bei deiner weiteren Entdeckungsreise :mrgreen:

Matze 7. Nov 2007 21:12

Re: [C++] Pointer-Problem: illegal indirection
 
Hi

Zitat:

Zitat von OregonGhost
Dann zieh dich schonmal warm an. Der Pfeil ->, die Klammern (), das Komma , , das Und &, der Punkt . usw. sind auch alle Operatoren. Aber das kranke daran ist, dass man sie (fast) alle überladen kann. Viel Spaß bei deiner weiteren Entdeckungsreise :mrgreen:

Dass ->, & und . auch Operatoren sind, wusste ich, aber () und , ist mir neu.
Das mit dem Überladen lasse ich vorerst mal, sonst geht hinterher gar nichts mehr und ich blicke überhaupt nicht mehr durch. :mrgreen:

Danke für die Info. Man lernt eben nie aus. :)

Torpedo 7. Nov 2007 21:19

Re: [C++] Pointer-Problem: illegal indirection
 
Zitat:

Zitat von Matze
Das mit dem Überladen lasse ich vorerst mal, sonst geht hinterher gar nichts mehr und ich blicke überhaupt nicht mehr durch. :mrgreen:

Dabei soll es genau das Gegenteil bewirken ;) Verkettete Listen auf die man mit [] zugreifen kann sind doch viel durchsichtiger. ;)

Khabarakh 7. Nov 2007 21:33

Re: [C++] Pointer-Problem: illegal indirection
 
Zitat:

Zitat von Matze
[...]aber () und , ist mir neu.

Das sind sogar zwei ganz bitterböse :mrgreen: . Die normale Klammer "(a)" ist kein Operator (jedenfalls habe ich noch nie gelesen, dass sie als ein solcher irgendwo definiert wird), in einer prozessornäheren UPN-Schreibweise würde sie ja auch wegfallen. Überladen lässt sie sich einmal als Cast-Operator "(a)b" und einmal als Function-Call-Operator "f()". Zum Komma sage ich lieber nichts, denn nachdem ich wie du gerade zum ersten Mal überhaupt von ihm gehört habe, will ich ihn bis morgen lieber wieder vergessen ;) .

@Torpedo: Fragt sich, ob man eine verkettete Liste wirklich indizieren will :mrgreen: .

OregonGhost 7. Nov 2007 21:41

Re: [C++] Pointer-Problem: illegal indirection
 
Zitat:

Zitat von Khabarakh
Die normale Klammer "(a)" ist kein Operator (jedenfalls habe ich noch nie gelesen, dass sie als ein solcher irgendwo definiert wird), in einer prozessornäheren UPN-Schreibweise würde sie ja auch wegfallen. Überladen lässt sie sich einmal als Cast-Operator "(a)b" und einmal als Function-Call-Operator "f()". Zum Komma sage ich lieber nichts, denn nachdem ich wie du gerade zum ersten Mal überhaupt von ihm gehört habe, will ich ihn bis morgen lieber wieder vergessen ;) .

Ja, ich habe vor ein paar Tagen zum ersten mal den Komma-Operator ernsthaft in einer Funktion benutzt, sogar relativ sinnvoll, und ich fühle mich ganz schmutzig. Dabei habe ich ihn nicht einmal überladen. Ich habe den entsprechenden Bereich stilecht mit
Code:
// HERE BE DRAGONS
kommentiert. Seltsamerweise habe ich ein paar Tage später (wenn ich so drüber nachdenke, es war heute) Code von jemand anderem gesehen, der auch auf seltsame Weise Gebrauch von diesem Operator machte.

Aber so ist das eben. Der Sprache selbst fehlen so viele praktische und heutzutage selbstverständliche Features, dafür hat sie so viele obszöne und esoterische Features, dass man damit fast alles machen kann, auch Dinge hinzufügen, die so nie vorgesehen waren, oder sich etwas syntaktische Vereinfachung verschaffen, indem man sie zweckentfremdet. Aber das lässt man lieber andere machen.

DMW 7. Nov 2007 21:42

Re: [C++] Pointer-Problem: illegal indirection
 
Zitat:

Zitat von Khabarakh
Wenn ich das richtig sehe, enthält das Array ja gar keine Zeiger, sondern direkt die Objekte (so langsam verstehe ich, warum C++ mit diesem Konzept ziemlich allein auf weiter Flur steht *g*)

Ja? Da bin ich aber gespannt :mrgreen:


Vom Überladen würde ich auch die Finger lassen, bis du einen guten Grund findest. Wenn du nicht unbedingt mathematisch orientierte Klassen schreibst (für die auch nur die arithmetischen Operatoren zu überladen wären, und das ist ja noch im Rahmen), wirst du das ohnehin kaum selbst machen müssen. Für die meisten Szenarien, in denen eine Überladung weiterer Operatoren sinnvoll wäre, gibt es in der STL (und natürlich in Boost) schon fertige Implementationen.

Daß man ->, [] und das unäre * überladen kann, ist übrigens für Iteratoren und Smart-Pointer essentiell. Letztere sind übrigens, wenn sinnvoll eingesetzt, so bequem wie ein Garbage-Collector, ohne mit dessen Nachteilen behaftet zu sein ;)

Es gibt allerdings tatsächlich einige Operatoren, die man nie überladen sollte, z.B. &&, || und , . Weiß der Geier, weshalb die Möglichkeit überhaupt besteht.

Und verkettete Listen indiziert man nicht einmal in C++ ;)


Zitat:

Zitat von OregonGhost
Der Sprache selbst fehlen so viele Features, dafür hat sie so viele obszöne und esoterische Features, dass man damit fast alles machen kann, auch Dinge hinzufügen, die so nie vorgesehen waren

Das ist doch gerade das schöne ;)


Zitat:

Zitat von OregonGhost
Aber das lässt man lieber andere machen.

Ich mache das eigentlich ganz gerne :mrgreen:

OregonGhost 7. Nov 2007 21:50

Re: [C++] Pointer-Problem: illegal indirection
 
Zitat:

Zitat von DMW
Zitat:

Zitat von Khabarakh
Wenn ich das richtig sehe, enthält das Array ja gar keine Zeiger, sondern direkt die Objekte (so langsam verstehe ich, warum C++ mit diesem Konzept ziemlich allein auf weiter Flur steht *g*)

Ja? Da bin ich aber gespannt :mrgreen:

Zugegeben, das ist eins der Features, das ich in dieser Form in anderen Sprachen vermisse. Auch wenn das mit Polymorphie schon wieder einen größeren Aufwand erfordert (jedoch, anders als in anderen Sprachen, keineswegs unmöglich und mit ein wenig Template-Code sogar relativ elegant zu erreichen ist).
Zitat:

Zitat von DMW
Für die meisten Szenarien, in denen eine Überladung weiterer Operatoren sinnvoll wäre, gibt es in der STL (und natürlich in Boost) schon fertige Implementationen.

Man kann sich sicherlich darüber streiten, ob es sinnvoll ist, die Shift-Operatoren als Stream-Operatoren zu überladen oder den Modulo für Stringformatierung :mrgreen:

DMW 7. Nov 2007 21:54

Re: [C++] Pointer-Problem: illegal indirection
 
Zitat:

Zitat von OregonGhost
Man kann sich sicherlich darüber streiten, ob es sinnvoll ist, die Shift-Operatoren als Stream-Operatoren zu überladen

Da braucht man gar nicht zu streiten. Ich finde die Dinger so grauenvoll wie du ;)


Zitat:

Zitat von OregonGhost
oder den Modulo für Stringformatierung :mrgreen:

Du meinst in printf? Das ist aber keine Operatorüberladung, sondern ein Relikt aus C (deshalb gibts da auch eigentlich keine Typsicherheit - aber auch das läßt sich mit C++ natürlich ändern ;) ). Und ich finde es _viel_ besser als die Streamoperatoren ;)

OregonGhost 7. Nov 2007 21:59

Re: [C++] Pointer-Problem: illegal indirection
 
Nein, boost::format verwendet den Modulo-Operator dafür. Nach dem Motto
Code:
boost::format("%1%, %2%") % "Hallo" % "Welt"
Hat interessante Vorteile, speziell im Vergleich zu Stream-Operatoren oder dem QString::arg() (oder, davon abgesehen, gegenüber printf). Ist in meinen Augen aber noch mehr zweckentfremdet.

Torpedo 7. Nov 2007 22:05

Re: [C++] Pointer-Problem: illegal indirection
 
Ich weiß nicht was ihr alle gegen einen []-Operator bei verketteten Listen habt. Man muss doch nicht bei jedem Zugriff die ganze Kette durchlaufen. :)
Code:
TStringList strl;
strl.add("Hallo");
strl.add("Welt");
for(int i = 0; i<strl.count(); i++)
  cout<<strl[i]<<"\n";
Den Such-Zeiger in der Liste muss man ja nicht jedes mal wieder an den Anfang setzen.
Aber kann schon sein, dass es bei verketteten Listen nicht benutzt wird.
Ein anderes Beispiel, wo es sicher benutzt wird, wäre zum Beispiel eine Klasse für Vektor-Berechnungen.
v3 = v1 + v2;
anstatt
v3 = v1.add(v2);

Dax 7. Nov 2007 22:06

Re: [C++] Pointer-Problem: illegal indirection
 
Da wäre das Komma doch passender gewesen.. *g*

DMW 7. Nov 2007 22:11

Re: [C++] Pointer-Problem: illegal indirection
 
Zitat:

Zitat von OregonGhost
Nein, boost::format verwendet den Modulo-Operator dafür. Nach dem Motto
Code:
boost::format("%1%, %2%") % "Hallo" % "Welt"

Stimmt, das gibts ja auch noch. Aber auch da präferiere ich printf.

boost.serialization verwendet auch <<, >> und & für das Streamen eines Wertes :shock:

OregonGhost 7. Nov 2007 22:18

Re: [C++] Pointer-Problem: illegal indirection
 
Naja, printf ist halt nicht zu gebrauchen, wenn man eine Anwendung international gestalten will, unterstützt keine benutzerdefinierten Typen und auch keine umgeleiteten Streams. Damit ist es zumindest für meinen Entwickleralltag vollkommen nutzlos. Streams sind, was Internationalisierung betrifft, natürlich auch nicht zu gebrauchen. Praktischerweise kann man boost::format aber in Streams schieben.
Hmm.
Wenn ich so drüber nachdenke... DESHALB hat man wohl die Shift-, sprich Schiebe-Operatoren dafür benutzt... um Dinge in den Stream hineinzuschieben :wall:

Was DAX' scherzhafte Bemerkung zum Kommaoperator angeht: Ich tippe mal, dass das auch der erste Gedanke der Boost-Leute war. Blöderweise kann man dann einen format-Aufruf nicht als Parameter übergeben, weil das Komma dann als Parameter-Trenner statt als Operator interpretiert wird.


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:33 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz