Funktion die eine dreidimensionales zeiger-array zurückgibt



  • Hallo,
    Kann mir irgendwer sagen, was mit dieser Funktion ist?

    #include <iostream>
    #include <stdlib.h>
    #include <math.h >
    using namespace std;
    long double*** machMatr(unsigned int const Anzahl);
    int main(int argc, char* argv[])
    {
    	int Grad;
    	cin>>Grad;
    
    	long double*** Determinanten = machMatr(Grad);
    	return 0;
    }
    long double*** machMatr(unsigned int const Anzahl)
    {
    	long double *Stellen=(long double*)malloc(2*Anzahl*sizeof(long double));
    	for (int i = 0; i < 2 * Anzahl; i++)cin >> Stellen[i];
    	long double static*** Det = (long double***)malloc((Anzahl+1) * sizeof(long double*));
    	for (unsigned int i = 0; i < Anzahl+1; i++)
    	{
    		Det[i] = (long double**)malloc(Anzahl * sizeof(long double));
    		for (unsigned int j = 0; j < Anzahl; j++) {
    			Det[i][j] = (long double*)malloc(Anzahl * sizeof(long double));
    		}
    	}
    	for (unsigned int i = 0; i < Anzahl + 1; i++)
    	{
    		for (unsigned int j = 0; j < Anzahl; j++) {
    			for (int k = 0; k < Anzahl; i++) {
    				if (i = k || i != Anzahl)Det[i][j][k] = Stellen[2 * j + 1];
    				else Det[i][j][k] = pow(Stellen[2 * j], k + 1);
    				cout << Det[i][j][k];
    			}
    			cout << "\n";
    		}
    		cout << "\n\n";
    	}
    
    	return Det;
    }
    

    Als Ergebnis bekomme ich eine endlosschleife Zahlen in die Konsole, ich kann mir vorstellen, dass das irgendwas mit Speicher zu tun hat, kann mir das aber nicht erklären. Ich habe schon verschiedene Zahlen getestet, es liegt wahrscheinlich an dem 'Det'.


  • Mod

    1. Das ist C mit einer einzigen Zeile C++ gemischt. Entscheide dich für eine der Sprachen, Mischen geht schief. Was soll's sein? Die Antwort, wie es richtig geht, hängt von der Sprache ab.
    2. Ein Array ist kein Pointer, ein Pointer ist kein Array. Entsprechend ist ein Pointer auf einen Pointer auf einen Pointer etwas ganz anderes als ein Array von einem Array von Arrays.
    3. Verteil nicht zufällig Schlüsselworte in deinem Programm, ohne sie zu verstehen. Was soll deiner Meinung nach das static in Zeile 18? C (und C++ auch) verzeiht kein Halbwissen. Du musst von jedem einzelnen Zeichen in deinem Programm genau wissen, wo und wieso du es setzt. Ebenso: Die Casts beim malloc (in C++ noch verzeihnlich, aber da ist malloc an sich unverzeihlich), das Gleichheitszeichen in Zeile 30 (welches musst du selber rausfinden, selber Schuld wenn man so viele Ausdrücke in eine Zeile schreibt), und wahrscheinlich noch mehr (kannst du sonst jedes Zeichen erklären?).
    4. Eine der Sachen aus Punkt 3 ist für die Endlosschleife verantwortlich. Aber das heißt nicht unbedingt, dass die Korrektur dafür sorgt, dass auch das richtige passiert, sondern bloß dass die Endlosschleife verschwindet. Gravierend ist immer noch Punkt 2, und was richtig ist, hängt von der Antwort auf Punkt 1 ab.
    5. Allgemein trägst du mit der Wahl deiner Variablen- und Funktionsnamen zu deiner eigenen Verwirrung bei. Determinanten sind gleich mach Matrix? Das macht keinen Sinn. Aber wenn du saubere Bezeichner wählst, dann liest sich ein Programm fast wie ein normaler Text (Englisch hilft dabei auch gewaltig!) und Logikfehler im Programm fallen schon direkt beim Lesen auf, weil der Text keinen Sinn ergibt. Aber hier hast du die Bezeichner ungünstig gewählt und das führt eher zu erhöhtem Denkaufwand, weil man sich von der normalen Bedeutung der Worte lösen muss, um dein Programm zu verstehen, weil die Worte in deinem Programm nicht ihre normale Bedeutung haben.


  • Die Endlosschleife ist jetzt weg, kann mal passieren, aber es gibt dennoch ein Problem mit Speicherzugriff.
    Ich weiß jetzt nicht, was so schlimm ist, an c in c++, wer das nicht will, der soll mit Java oder Python programmieren.
    Was aber soll denn jetzt problematisch daran sein, einen Zeiger mit static - auch wenn es überflüssig wäre - zu benutzen und mit malloc Speicher anzufordern?



  • Dann rufe die Funktion zweimal auf (mit gleicher oder unterschiedlicher Anzahl) ...
    Du solltest schon verstehen, was die einzelnen Sprachelemente bewirken.

    Teste es mal selber mit dem Debugger (Einzelschritt), falls du (noch) nicht weißt, was static bedeutet.



  • @Ichwerdennsonst sagte in Funktion die eine dreidimensionales zeiger-array zurückgibt:

    Ich weiß jetzt nicht, was so schlimm ist, an c in c++, wer das nicht will, der soll mit Java oder Python programmieren.
    Was aber soll denn jetzt problematisch daran sein, einen Zeiger mit static - auch wenn es überflüssig wäre - zu benutzen

    Nein, umgekehrt: wer nicht lernen will, wie C und C++ genau funktionieren, was Schlüsselwörter wie static bedeuten, sollte auf eine andere Sprache zurückgreifen. Umso mehr gilt das für Personen, die auch nach einem Hinweis darauf noch immer nicht glauben, dass das ein Problem sei (man könnte ja auch mal nachschauen, was static so tut - zum Beispiel hier https://en.cppreference.com/w/cpp/language/storage_duration#Static_local_variables - es reicht schon, den ersten Absatz zu lesen).

    Malloc: komplett unidiomatisch in C++. Ruft den Konstruktor nicht auf, geht - wenn überhaupt - nur für POD-Typen und eigentlich müsste man danach noch ein placement-new machen, um die Lebenszeit des Objektes zu starten (könnte sein, dass das ab C++17 oder 20 bei PODs auch standardkonform nicht mehr nötig ist und darf auch vorher funktioniert haben - aber allein dass man sich Gedanken darüber machen muss, spricht schon dagegen, dieses Konstrukt zu verwenden). In C++ verwendet man außerdem (im Regelfall) keine manuelle Speicherverwaltung, dabei kann man viel zu leicht viel zu viel falsch machen.

    Und in C ist malloc zwar ok, aber erstens brauchst du keine Casts und zweitens trennt man Speichererstellung vom Befüllen (gut, gilt auch für C++). Idiomatischer Code sorgt dafür, dass du weniger falsch machst und der Code besser lesbar ist.


Log in to reply