mathematische Matrix

  • Original von M.A.X
    Wenn Du _EIN_ einziges Mal ein Programm geschrieben hättest, bei dem es wirklich auf Geschwindigkeit ankommen würde und nicht nur über premature optimization schwafeln würdest, dann hättest du nicht so ne arrogante antwort gegeben.


    Würde man da nicht eh alles mit einem eindimensionalen Array machen? "Nur mal ne Frage". Nicht in den falschen Hals kriegen. ;) ^^
  • Hi, ich habe jetzt noch eine Frage. Der folgende Code soll das Problem ungefähr beschreiben. Ich entferne also aus dieser Matrix die Reihen aus dem NSIndexSet selectedRows. Das funktioniert auch soweit, bis ich den Speicher, der ja frei wird, wieder freigeben will. Was mache ich in der auskommentierten Zeile falsch? Die letzte Reihe der Matrix ist immer Müll.

    Quellcode

    1. int rows = 10;
    2. int i;
    3. int** matrix = (int**)malloc(sizeof(int)*rows);
    4. for (i=0; i<rows; i++) matrix[i] = (int*)malloc(sizeof(int)*3);
    5. for (i=0; i<rows; i++) matrix[i][0] = i+1;
    6. for (i=0; i<rows; i++) NSLog(@"%i",matrix[i][0]);
    7. NSIndexSet* selectedRows = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(3,2)];
    8. i = 0;
    9. int offset = 0;
    10. while (i<rows) {
    11. if ([selectedRows containsIndex:i+offset]) {
    12. int j;
    13. rows--;
    14. for (j=i; j<rows; j++) {
    15. matrix[j] = matrix[j+1];
    16. }
    17. //free(matrix[rows]);
    18. offset++;
    19. } else {
    20. i++;
    21. }
    22. }
    23. NSLog(@"---");
    24. for (i=0; i<rows; i++) NSLog(@"%i",matrix[i][0]);
    Alles anzeigen


    @ -Nuke-: Letztendlich ist eh alles eindimensional.
  • Original von -Nuke-
    Würde man da nicht eh alles mit einem eindimensionalen Array machen? "Nur mal ne Frage". Nicht in den falschen Hals kriegen. ;) ^^

    Das kann ich dir nicht genau sagen, glaube aber, dass das *kaum* einen unterschied macht. Wenn du ein array zwei-dimensional anlegst, dann ist das im prinzip auch nur ein eindimensionales, denn die daten liegen im speicher ja alle hintereinander. der macht dann einfach aus a[x][y] einfach a[x*breite + y]. bei dynamischen ist das allerdings etwas anders. Da wird ja jede zeile separat alloziert und somit müssen die stücke nicht in einer reihe oder beieinander liegen. Dennoch glaube ich (eher aus dem bauch heraus) kaum, dass das auf assemblerebene noch einen wirklichen unterschied zwischen dynamischen und statischen arrays gibt...
  • Original von mackz
    @ -Nuke-: Letztendlich ist eh alles eindimensional.


    Hi. Sorry, eine Sache will ich noch los werden.

    Sicherlich, aber das liegt im Endeffekt an der C-Implementierung. Deswegen bin ich auch vorsichtig mit der Annahme "C = am schnellsten". Es wäre nicht das erste mal das Standard Java oder C# oder Python -Code hochoptimierten C-Code bei weitem abhängt. Sei es bei mathematischen Funktionen oder String-Operationen...

    Hier zählt die Implementierung. Also bitte nicht gleich an die Gurgel gehen. Wie wäre es mal mit einem allgemeinen Benchmark, in einem neuen Thread?
  • Original von Tom9811
    Manchmal sind c Kenntnisse bei objc

    Welche C-Kenntnisse bei Objective-C. Was haben denn Objective-C-Arrays mit C zu tun?

    doch von Vorteil.

    Welcher Vorteil denn von Objective-C-Arrays?

    Ich meinte mit c Kenntnisse, dass man es nicht schadet, wenn man weiss, wie man dynamisch mit malloc Speicher anlegt. Auf arrays irgendeiner machart hab ich damit nicht gemeint.


    Manfred
  • Original von -Nuke-
    Hier zählt die Implementierung.

    das stimmt
    Also bitte nicht gleich an die Gurgel gehen.

    *ggg* Das ist alles aufgestauter frust über hunderte postings ;)
    Wie wäre es mal mit einem allgemeinen Benchmark, in einem neuen Thread?

    wäre ich dabei...

    Max
  • Original von mackz
    Ich habe meinen Fehler gefunden. Man sollte schreiben:

    Quellcode

    1. matrix[rows]=nil;
    2. free(matrix[rows]);

    Nur weiß ich nicht, ob das free überhaupt noch benötigt wird.

    Wenn du das free nicht machst, hast Du ein speicher leck. Aber nicht als zweites. Siehe posting von M.A.X.

    Manfred
  • Original von mackz
    Ich habe meinen Fehler gefunden. Man sollte schreiben:

    Quellcode

    1. matrix[rows]=nil;
    2. free(matrix[rows]);

    Nur weiß ich nicht, ob das free überhaupt noch benötigt wird.

    Oh nein, das ist nicht der Fehler. Das ist ein neuer Fehler, der (noch) ein Speicherloch erzeugt. Die Funktion free() benötigt die Adresse des freizugebenden Speicherbereichs und die schmeißt Du vor dem Aufruf von free() weg.

    Der Fehler in Deinem Code oben ist ein anderer. Die Auskommentierte Zeile 23 gehört vor die for-Schleife (also nach Zeile 19) und Du musst i und nicht rows als Index angeben, denn Du willst doch die Zeile mit dem Index i löschen. Dein Code gibt aber immer den Speicher für die letzte Zeile frei, d.h. sobald free() zum zweiten Mal aufgerufen wird, gibst Du Speicher frei, der bereits freigegeben ist.

    Michael
  • Original von Michael
    Ach, und noch was. Zeile 4 sollte so aussehen

    Quellcode

    1. int** matrix = (int**)malloc(sizeof(int *) * rows);
    denn sizeof(int) ist nicht zwangläufig gleich sizeof(int *)

    Stimmt, die Zeigergroesse muss nicht gleich der Groesse des Datentyps int sein.
    Wobei es auch egal ist, ob man sizeof(void *),(char *) oder (int *) schreibt. Kommt ueberall das gleiche raus.
    Zeiger haben auf 32 Bit Systemen normalerweise auch 32 Bit.

    Manfred

    Update: die Codezeile ist im Codeposting von Mackz verschwunden. Geaendert?

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von asrael ()

  • Eben, die Kirche im Dorf lassen. Wozu jetzt eine Gefahr ans Bein binden, die ich möglicherweise gar nicht benötige. Wir wissen doch gar nicht, was der OP wie wann macht. Wieso macht man sich also Gedanken über die Geschwindigkeit.

    Ja, wenn man sorgfältig programmieren würde. Komischerweise gehe ich bei den mal schnell zusammengesuchten Berispielen (die alle aus den letzten Tagen(!) stammen) davon aus, dass es sich um sorgfältige Programmierer handelt. Du hast alles dabei: Große Unternehmen, OO-Projekte die täglich 12398721987-fach eingesetzt werden. Dennoch passieren die Fehler. Das liegt nicht daran, dass die Leute unsorgfältig sind, sondern schlicht daran, dass Fehler passieren.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Wenn Du _EIN_ einziges Mal ein Programm geschrieben hättest, bei dem es wirklich auf Geschwindigkeit ankommen würde

    Habe ich, sogar zu Zeiten, als du noch in den Windeln sast. 3D - Rendering mit Tiefenpuffer auf einem ST ist ein Performance-Problem.

    Mess-Daten von einem Transputernetzwerk zu bekommen, das im Mega-Sample-Bereich arbeitet und diese in Echtzeit darzustellen, ist ein Performance-Problem.

    Man kann das schlau lösen oder weniger schlau.

    Ich glaube nicht, dass du mir an Erfahrung das Wasser reichen kannst.

    Es ist hier aber nicht so, dass wir auch nur den Anflug einer Ahnung davon haben, wie sehr es auf Performance ankommt. Deshalb heißt das auch premature Optimization.

    und nicht nur über premature optimization schwafeln würdest,

    a) Schwafeln machst gerade du
    b) Ist das Zitat nicht von mir, sondern von Donald Knuth

    dann hättest du nicht so ne arrogante antwort gegeben.

    Arrogant war einzig und allein dein Beitrag, nachdem der gute MAX keine Fehler macht, aber die halbe Welt dann eben doch. Findest du es nicht arrogant, dich für besser als zahlreiche Groß-Unternehmen und OS-Programmierer zu halten?

    Ich habe nur gesagt, dass es nicht zwangsläufig zu Buffer Overflows kommen muss,

    a) habe ich das nicht behauptet.
    b) stimmt das nicht. Du hast gesagt, dass wenn man aufpasst, das nicht vorkommt. Das ist ganz simpel extremer Unfug, weil man eben nicht immer sorgsam ist. Und all diese Leute dürften deine Programmierfähigkeiten bei weitem übersteigen, vor allem in der Summe.

    nur weil man in C schreibt

    Was hat [] mit C zu tun?

    und dass man, wenn man so ein dämliches beispiel macht wie du es klar ist,

    Das Beispiel sollte den Effekt verdeutlichen. Das Problem bei Buffer Overflows ist, dass man sie nicht erkennt, so dass ein "reales" Beispiel eben nicht erkannt wird. Darum geht es gerade.

    Wenn man sich nicht dämlich anstellt, erkennt man das auch, lieber MAX.

    dass das passiert. Was DU aber sagst ist, dass diese Entwickler alles Idioten sind, weil sie nicht in cocoa oder sonstwas schreiben

    Nein, das sage ich nicht. Ich halte etwa MACH nicht für von Idioten geschireben.

    Ich sage nur, dass man eine solche Gefahr nicht eingehen sollte, wenn es nicht sein muss, weil jeder Fehler macht und das ganze intellektuell nicht einfach ist. Da du dich für unfehlbar hältst, lieber Papst MAX I., trifft das natürlich nicht auf dich zu.

    Merwürdig ist jedoch, warum jhetzt schon zwei Fehler in der Sourve aufgetaucht sind. Hmm, was man dazu nur sagen soll.

    Sag mal, den Begriff "premature" verstehst du schon?

    Was das nun wieder mit C zu tun hat, erschließt sich mir gar nicht.

    und deshalb buffer overflows produzieren. Bis heute habe ich nicht den sinn und zweck dieser deiner Argumentation verstanden. Sag ihn mir uns ich will ruhe geben.

    Was hast du an den Beispielen nicht verstanden? Sorry, aber wenn du nicht bemerkst, dass in der Realität täglich auf Sicherheitsseiten Buffer-Overflows veröffentlicht werden (und das sind nur diejenigen, die ein Sicherheitspüroblem darstellen, nicht diejenigen, die einfach SW zum Absturz bringen), dann weiß ich auch nicht, wie ich es dir noch erklären soll.

    Wenn täglich Autos gegen eine Mauer fahren, weil die Bremsen versagen, dann bestehe ich auf besseren Bremsen. Was daran nicht zu vcerstehen ist, erschließt sich mir nicht. Ich mutmaße aber, dass jede weitere Erläuterung einen untauglichen Versuch darstellt.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Ich meinte mit c Kenntnisse, dass man es nicht schadet, wenn man weiss, wie man dynamisch mit malloc Speicher anlegt.

    Was hat das mit C zu tun? Das geht auch in Objective-C und es ging schon in B und es ging sogar schon BCPL.

    malloc() hat soviel mit C zu tun wie a = 2+3. Es gab es vorher, es gab es nachher.

    Auf arrays irgendeiner machart hab ich damit nicht gemeint.

    Ich meinte Array der Machart [], welche auch ein Objetive-C existieren. Wen nich eine datei.m habe, meckert er mir jedenfalls nicht "int einFeld[]" an.

    Und juchhuuu! ich benutze auch C-Felder. Nachdem ich erkannt habe, dass ich sie aus $GRÜNDEN benötige, nicht vorher.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Nur noch ein Hinweis an die wirklichen und selbsternannten C-Experten hier:

    Was der OP macht ist nicht die Allozierung eines einhheitlichen Blockes. Im Speicher sieht die Belegung von

    Quellcode

    1. int **feld = (int**)malloc( sizeof(int) * rows * 3);
    und

    Quellcode

    1. int **feld = (int**)malloc( sizeof(int*) * rows;
    2. for( ...
    3. feld[i] = (int*)malloc( sizeof(int) * 3);
    NICHT gleich aus. Das führt zu einer völlig anderen Speicherbelegung. Zudem führt 2) mutmaßlich zu einem Speicherverschwendung, welche die eines NSArrays deutlich übersteigen dürfte. Wenn schon, dann bitte 1) nehmen.

    Ich finde es schon erstaunlich, dass die C-Experten hier zu einem "C-Array" raten, weil es vorteilhaft sei, es gleichzeitig ber gänzlich unvorteilhaft allozieren.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Original von mackz
    Ich habe nichts verändert.

    Ich sehe die Zeile auch noch. :D

    Noch ein weiterer Verbesserungsvorschlag. Wenn Du durch ein Array durch läufst und dabei einzelne Elemente löschst, empfiehlt es sich den Durchlauf von hinten nach vorne zu machen. Das vereinfacht die Sache erheblich:

    Quellcode

    1. i = rows;
    2. while (i--)
    3. {
    4. if ([selectedRows containsIndex:i])
    5. {
    6. int j;
    7. rows--;
    8. free(matrix[i]);
    9. for (j=i; j<rows; j++)
    10. matrix[j] = matrix[j+1];
    11. }
    12. }
    Alles anzeigen
    Michael