Problem mit Puffer ferster Größe

  • C#

Es gibt 9 Antworten in diesem Thema. Der letzte Beitrag () ist von Artentus.

    Problem mit Puffer ferster Größe

    Hallo zu dieser späten Stunde.

    Ich habe gerade folgende Struktur erstellt:

    C#-Quellcode

    1. public unsafe struct Matrix2x3
    2. {
    3. fixed float values[6];
    4. public float this[int x, int y]
    5. {
    6. get
    7. {
    8. if (x < 0 || x > 1 || y < 0 || y > 2)
    9. throw new IndexOutOfRangeException();
    10. return values[x * 3 + y];
    11. }
    12. set
    13. {
    14. if (x < 0 || x > 1 || y < 0 || y > 2)
    15. throw new IndexOutOfRangeException();
    16. values[x * 3 + y] = value;
    17. }
    18. }
    19. //...
    Im Codeditor wird mir kein Fehler angezeigt, beim Kompilieren erhalte ich jedoch in den Zeilen 12 und 19 diesen Fehler:

    Quellcode

    1. Sie können keine Puffer fester Größe verwenden, die in nicht festen Ausdrücken enthalten sind. Verwenden Sie die fixed-Anweisung.
    Wer dreht hier durch, ich oder Visual Studio? Wo soll ich denn da ne Fixed-Anweisung verwenden?

    Edit: es scheint so, als ob das hier funktionieren würde:

    C#-Quellcode

    1. public unsafe struct Matrix2x3
    2. {
    3. fixed float values[6];
    4. public float this[int x, int y]
    5. {
    6. get
    7. {
    8. if (x < 0 || x > 1 || y < 0 || y > 2)
    9. throw new IndexOutOfRangeException();
    10. fixed (float* p = values)
    11. {
    12. return p[x * 3 + y];
    13. }
    14. }
    15. set
    16. {
    17. if (x < 0 || x > 1 || y < 0 || y > 2)
    18. throw new IndexOutOfRangeException();
    19. fixed (float* p = values)
    20. {
    21. p[x * 3 + y] = value;
    22. }
    23. }
    24. }
    25. }
    Warum ist das so? Warum muss ich das nochmal anpinnen?

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Artentus“ ()

    Wie du weißt, arbeite ich auch sehr viel mit unsafe und allem was dazu gehört. Und mir ist das auch nur so bekannt, dass du auf sogenannte "Fixed Size Buffers" nur über ein einen Pointer zugreifen kannst. Den Pointer wiederum bekommst du über ein weiteres fixed Schlüsselwort.
    Alternativ kannst du natürlich nen GCHandle verwenden, was hier aber sicherlich fehl am Platz ist. Ansonsten ist letztere Schreibweise sicher richtig.
    Siehe auch noch was msdn dazu sagt: msdn.microsoft.com/en-us/library/zycewsya.aspx


    Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.
    Eine Sache finde ich aber seltsam.
    Das Problem tritt nur auf, wenn ich auf this zugreife. Ich hab z.B. diese statische Property:

    C#-Quellcode

    1. public static Matrix2x3 Identity
    2. {
    3. get
    4. {
    5. Matrix2x3 m = default(Matrix2x3);
    6. m.values[0] = 1.0f;
    7. m.values[4] = 1.0f;
    8. return m;
    9. }
    10. }
    Und hier bekomme ich keinen Fehler, im Gegenteil, ich bekomme einen Fehler, wenn ich versuche das nochmal anzupinnen.
    Wenn du meinst, dass eine variable Adresse keinen Unterschied macht, dann verändere deine letzte Matrix so, dass man über eine Variable etwas ändert (wie am Anfang).

    So wie ich das verstehe, liegt der Unterschied in Speichermanipulation (du kannst mit Variablen auf Speicherinhalte zugreifen, die gar nicht mehr in deiner Struktur liegen - es ist ein sehr beliebter und schwer zu findender Fehler in C, weil da Speichermanipulationen unbegrenzt erlaubt sind).