Access Violation

  • C#
  • .NET 5–6

Es gibt 8 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    Access Violation

    Moin,

    ich habe hier das Phänomen in C#, dass ich Access Violation Fehler erhalte.

    Man sehe sich bitte folgendes Beispiel an:

    C#-Quellcode

    1. private void BereinigenSpeicherOhneKomplement()
    2. {
    3. List<Zug> nächste = new();
    4. IEnumerable<Zug> collection = züge[maxzug];
    5. for(int loop = maxzug; maxzug >= startzug; loop--)
    6. {
    7. nächste.Clear();
    8. foreach(var item in collection)
    9. {
    10. IEnumerable<Zug> tmp = züge[loop - 1];
    11. var t = tmp.Where(xx => item.Vorgänger == xx.Stellung);
    12. nächste.AddRange(t);
    13. }
    14. züge[loop].Clear();
    15. collection = nächste;
    16. }
    17. }


    In Zeile 14, also dem AddRange bricht meine Anwendung ab mit Access Violation.

    Auch wenn ich beim Debuggen im Befehlsfenster ein ? t.Count() absetze kracht es. Da kommt dann ein StackOverflow, also möglicherweise eine Endlosschleife??

    Ich kapier grad nix. Da scheint doch intern irgendwas durch den Wind, oder?

    Kennt jemand eine solche Situation und hat einen Tipp was das Problem sein könnte. VS habe ich schon repariert.


    Noch zur Info:

    C#-Quellcode

    1. internal SynchronizedCollection<Zug>[] züge = new SynchronizedCollection<Zug>[32]; // 2023-01-25


    C#-Quellcode

    1. internal class Zug
    2. {
    3. public Stellung Vorgänger { get; set; }
    4. public Stellung Stellung { get; set; }
    5. public Zug(Stellung vorgänger, Stellung stellung)
    6. {
    7. Vorgänger = vorgänger;
    8. Stellung = stellung;
    9. }
    10. public static implicit operator ZugEntity(Zug zug) { return new() { Stellung = zug.Stellung, Vorgänger = zug.Vorgänger }; }
    11. public static implicit operator Zug(ZugEntity e) { return new(e.Vorgänger, e.Stellung); }
    12. }
    13. internal class Stellung
    14. {
    15. private long _content;
    16. public long Content => _content;
    17. public Stellung(long content)
    18. {
    19. _content = content;
    20. }
    21. public static implicit operator Stellung(long l) => new Stellung(l);
    22. public static implicit operator long(Stellung p) => p._content;
    23. public static bool operator ==(Stellung p1, Stellung p2) => p1.Equals(p2);
    24. public static bool operator !=(Stellung p1, Stellung p2) => !p1.Equals(p2);
    25. public override bool Equals(object obj) { return object.Equals(obj, this); }
    26. public override int GetHashCode() { return _content.GetHashCode(); }
    27. public static Stellung StartStellung => new Stellung (((long)1 << 33) - 1);
    28. }


    züge wird über Parallel.ForEach gefüllt und da List<> oder ähnliche Typen nicht threadsicher sind, muss es ein SynchronizedCollection sein. Ob aber das die Probleme verursacht, kann ich nicht sagen.

    Gruß

    MQ
    @MasterQ Hast Du mal einen Haltepunkt auf Zeile 14 gesetzt und Dir angesehen, was in t steht?
    item.Vorgänger scheint da ggf. fehlzugreifen.

    C#-Quellcode

    1. public override bool Equals(object obj) { return object.Equals(obj, this); }
    gibt ggf. ein StackOverflow.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Auch wenn ich beim Debuggen im Befehlsfenster ein ? t.Count() absetze kracht es


    Also t ist schon definitiv kaputt. Der Crash kommt aber erst im AddRange wenn was mit t gemacht wird. Hier mal Screenshots




    Nachdem ich t.Count() absetzte, oder auch irgendetwas anderes wie t.ToList() oder t.ElementAt(1) kommt der oben gezeigte Fehler.

    An sich enthält t schon das richtige Element, ist aber dennoch intern irgendwie kaputt. Kann das am Überschriebenen Stellung.Equals liegen? Ich denke nicht, denn da wird nur bool zurückgegeben und ich vergleiche letztlich zwei long. Inwiefern sollte das was kaputt machen? tmp.Where() schmeißt definitiv Elemente weg, bzw. kopiert nicht alle aus dem Quellelement ins Zielelement.

    Aber das ist doch Standardzeugs und nichts besonderes?

    ... Moment mal ... Mir kommt einen Idee ...

    folgende Zeile verursacht kein Blödsinn

    C#-Quellcode

    1. var t = tmp.Where(xx => item.Vorgänger.Content == xx.Stellung.Content);


    Mir stellt sich jetzt die Frage, was ich mit meinen eigenen Operatoren und mit Equals falsch mache.

    EDIT:

    diese Zeile verursacht das Problem.

    C#-Quellcode

    1. public override bool Equals(object obj) { return object.Equals(obj, this); }


    Ich habe sie jetzt ersetzt durch

    C#-Quellcode

    1. public override bool Equals(object x) { return (x as Stellung).Content == _content; }


    Wie kann die Zeile oben was kaputt machen?

    Zu Fuß kommt kein Fehler



    Achselzuck

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

    @MasterQ Kannst Du mal ein kleines Programm posten, das Deinen Effekt (getestet!) reproduziert?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hallo,
    deine Equals-Implementierung ist nicht vollständig/falsch. Was passiert, wenn das übergeben Objekt null ist? Ich würde außerdem das Interface IEquatable implementieren.
    Beispiel:

    C#-Quellcode

    1. class C : IEquatable<C>
    2. {
    3. public int Value { get; set; }
    4. public override bool Equals(object obj)
    5. {
    6. return Equals(obj as C);
    7. }
    8. public bool Equals(C other)
    9. {
    10. return other != null &&
    11. other.Value == Value;
    12. }
    13. public override int GetHashCode()
    14. {
    15. return HashCode.Combine(Value);
    16. }
    17. }
    Sry, hat bissl gedauert.


    ISliceUrPanties schrieb:

    Hallo,
    deine Equals-Implementierung ist nicht vollständig/falsch. Was passiert, wenn das übergeben Objekt null ist? Ich würde außerdem das Interface IEquatable implementieren.


    OK, eine Abfrage nach NULL macht Sinn, ist aber hier nicht das Problem.

    Im Anhang mein Code etwas zusammengeschrumpelt. Es bleibt bei der Problemzeile, jetzt aber mit einem StackOverflow. Das grundlegende Problem sollte aber das gleiche sein.
    Dateien
    • VBParadise.zip

      (6,72 MB, 60 mal heruntergeladen, zuletzt: )
    @MasterQ Der hier:
    Spoiler anzeigen

    C#-Quellcode

    1. internal class Stellung : IEquatable<Stellung>
    2. {
    3. private long _content;
    4. public long Content => _content;
    5. public Stellung(long content)
    6. {
    7. _content = content;
    8. //id = DateTime.Now.Ticks;
    9. }
    10. public static implicit operator Stellung(long l) => new Stellung(l);
    11. public static implicit operator long(Stellung p) => p._content;
    12. public static bool operator ==(Stellung p1, Stellung p2) => p1.Equals(p2);
    13. public static bool operator !=(Stellung p1, Stellung p2) => !p1.Equals(p2);
    14. public override int GetHashCode() { return _content.GetHashCode(); }
    15. public bool Equals(Stellung other)
    16. {
    17. return object.Equals(other, this);
    18. }
    19. //public override bool Equals(object obj)
    20. //{
    21. // return Equals(obj as Stellung);
    22. //}
    23. }

    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!