Serialisierung - Access violation

  • C#
  • .NET (FX) 4.5–4.8

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

    Serialisierung - Access violation

    Hallo.

    Und zwar habe ich eine List(of Figur). Die Klasse Figur sieht so aus:

    C#-Quellcode

    1. using System;
    2. using System.Drawing;
    3. namespace FigurenBibliothek
    4. {
    5. /// <summary>
    6. /// Zeichenbare 2D Figur
    7. /// </summary>
    8. [Serializable]
    9. public abstract class Figur : Punkt
    10. {
    11. // Konstruktoren
    12. public Figur(Punkt pos) : base(pos.X, pos.Y) {
    13. // VOID
    14. }
    15. // Methoden
    16. public abstract void Zeichnen(Graphics g);
    17. public abstract float FlaecheBerechnen();
    18. public abstract float GetBreite();
    19. public abstract float GetHoehe();
    20. public virtual bool Treffer(Punkt position) {
    21. return
    22. position.X >= X && position.X <= X + GetBreite() &&
    23. position.Y >= Y && position.Y <= Y + GetHoehe();
    24. }
    25. }
    26. }


    Mein Ziel: Diese List(of Figur) in einer Datei serialisiert abzulegen, um
    so ein Speichern/Laden zu ermöglichen.


    Meine Klasse zum Speichern und Laden sieht derzeit so aus:

    C#-Quellcode

    1. using System;
    2. using System.Collections.Generic;
    3. using System.IO;
    4. using System.Linq;
    5. using System.Runtime.Serialization;
    6. using System.Runtime.Serialization.Formatters.Binary;
    7. using System.Text;
    8. namespace FigurenBibliothek
    9. {
    10. [Serializable]
    11. public class LoadOrSave
    12. {
    13. [Serializable]
    14. public class DrawingObject
    15. {
    16. public List<Figur> figuren;
    17. }
    18. public static List<Figur> LoadOrSaveIt(List<Figur> items)
    19. {
    20. IFormatter formatter = new BinaryFormatter();
    21. String fileToReadFrom = "Drawing.cool";
    22. List<Figur> toReturn = new List<Figur>();
    23. if (!File.Exists(fileToReadFrom))
    24. {
    25. File.Create(fileToReadFrom);
    26. }
    27. Stream stream = new FileStream(fileToReadFrom, FileMode.Open, FileAccess.Read, FileShare.Read);
    28. if (items != null)
    29. {
    30. DrawingObject dataToSave = new DrawingObject();
    31. dataToSave.figuren = items;
    32. formatter.Serialize(stream, dataToSave);
    33. stream.Close();
    34. return toReturn;
    35. }
    36. if (stream != null)
    37. {
    38. DrawingObject toReadFrom = (DrawingObject)formatter.Deserialize(stream);
    39. toReturn = toReadFrom.figuren;
    40. }
    41. stream.Close();
    42. return toReturn;
    43. }
    44. }
    45. }




    Das Klassenkonstrukt, in dem ich dieses Laden/Speichern verwenden möchte, fängt
    wie folgt an:


    C#-Quellcode

    1. using FigurenBibliothek;
    2. using System;
    3. using System.Collections.Generic;
    4. using System.Drawing;
    5. using System.IO;
    6. using System.Runtime.Serialization;
    7. using System.Runtime.Serialization.Formatters.Binary;
    8. using System.Windows.Forms;
    9. namespace FigurenBibliothek
    10. {
    11. public partial class AppForm : Form
    12. {
    13. private List<Figur> figuren = new List<Figur>(); // leere Liste
    14. private Punkt mausPunkt = null;
    15. private Punkt figurPunkt = null;
    16. private Figur trefferFigur = null;
    17. public AppForm(Figur[] figuren) {
    18. this.figuren.Clear();
    19. this.figuren.AddRange(figuren);
    20. InitializeComponent();
    21. this.DoubleBuffered = true;
    22. }
    23. private void AppForm_Paint(object sender, PaintEventArgs e) {
    24. List<Figur> items = LoadOrSave.LoadOrSaveIt(null);
    25. if (items != null)
    26. {
    27. figuren.Clear();
    28. figuren.AddRange(items);
    29. }
    30. foreach (Figur figur in figuren) {
    31. figur.Zeichnen(e.Graphics);
    32. }
    33. }



    Jedes Mal wenn ich Debuggen möchte, schmiert das Programm direkt ab.


    Sofern ich diese Zeilen hier auskommentiere:

    C#-Quellcode

    1. //List<Figur> items = LoadOrSave.LoadOrSaveIt(null);
    2. //if (items != null)
    3. //{
    4. // figuren.Clear();
    5. // figuren.AddRange(items);
    6. //}




    kann ich es wieder starten. Also muss es an der Serialisierung liegen.

    Fehler:

    Quellcode

    1. Ausnahme ausgelöst: "System.Runtime.Serialization.SerializationException" in mscorlib.dll
    2. Das Programm "[5648] FigurenAnwendung.vshost.exe" wurde mit Code -1073741819 (0xc0000005) 'Access violation' beendet.


    Kann mir jemand vielleicht helfen?
    Selbst wenn du deinen Code ohne die Fehlermeldung hinbekommst, wird er dir nix anzeigen. Da du in der Klasse AppForm in Zeile 29 die Funktion LoadOrSaveIt mit null aufrufst und gemäß der Logik der Funktion LoadOrSaveIt wird dir lediglich eine leere Instanz der Klasse List<Figur> zurück geliefert. *just say'in*

    Zu dem eigentlichen Problem: Hast du schon mal versucht das Attribut weg zu lassen?
    In general (across programming languages), a pointer is a number that represents a physical location in memory. A nullpointer is (almost always) one that points to 0, and is widely recognized as "not pointing to anything". Since systems have different amounts of supported memory, it doesn't always take the same number of bytes to hold that number, so we call a "native size integer" one that can hold a pointer on any particular system. - Sam Harwell
    Das [Serializable]-Attribut
    In general (across programming languages), a pointer is a number that represents a physical location in memory. A nullpointer is (almost always) one that points to 0, and is widely recognized as "not pointing to anything". Since systems have different amounts of supported memory, it doesn't always take the same number of bytes to hold that number, so we call a "native size integer" one that can hold a pointer on any particular system. - Sam Harwell
    @SSD Kannst Du mal so viel Code posten, dass wir Deinen Effekt reproduzieren können?
    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!
    Also ich kann diese Accss Violation nicht nachvollziehen/nachbilden. Wenn ich die Anwendung starte, dann kommt bei mir zwar eine Serialisieruns-Exception, aber deren Fehlernachricht bezieht sich auf einen "leeren Datenstrom"

    Spoiler anzeigen

    System.Runtime.Serialization.SerializationException wurde nicht behandelt.
    HResult=-2146233076
    Message=Es wird versucht, einen leeren Datenstrom zu deserialisieren.
    Source=mscorlib
    StackTrace:
    bei System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
    bei System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream)
    bei FigurenBibliothek.LoadOrSave.LoadOrSaveIt(List`1 items) in C:\Users\user\Downloads\FigurenAnwendung-v2\FigurenAnwendung-v2\FigurenAnwendung-v2\FigurenBibliothek\LoadOrSave.cs:Zeile 42.
    bei FigurenBibliothek.AppForm.AppForm_Paint(Object sender, PaintEventArgs e) in C:\Users\user\Downloads\FigurenAnwendung-v2\FigurenAnwendung-v2\FigurenAnwendung-v2\FigurenBibliothek\AppForm.cs:Zeile 37.
    bei System.Windows.Forms.Control.OnPaint(PaintEventArgs e)
    bei System.Windows.Forms.Form.OnPaint(PaintEventArgs e)
    bei System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer)
    bei System.Windows.Forms.Control.WmPaint(Message& m)
    bei System.Windows.Forms.Control.WndProc(Message& m)
    bei System.Windows.Forms.Form.WndProc(Message& m)
    bei System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
    InnerException:

    In general (across programming languages), a pointer is a number that represents a physical location in memory. A nullpointer is (almost always) one that points to 0, and is widely recognized as "not pointing to anything". Since systems have different amounts of supported memory, it doesn't always take the same number of bytes to hold that number, so we call a "native size integer" one that can hold a pointer on any particular system. - Sam Harwell
    @Radinator Jou.
    @SSD Es knallt noch, wenn items != null ist. Hier musst Du den Stream für FileAccess.Write bereitstellen.
    Am besten ist es, wwenn Du eine Lese- und eine Schreibroutine implementierst.
    =============
    Schreiben:

    C#-Quellcode

    1. stream = new FileStream(fileToReadFrom, FileMode.Create, FileAccess.Write, FileShare.Write);
    Lesen (wie gehabt):

    C#-Quellcode

    1. stream = new FileStream(fileToReadFrom, FileMode.Open, FileAccess.Read, FileShare.Read);
    =====
    In der Paint-Routine solltest Du die Datei nicht auslesen!!!
    =====
    Jetzt musst Du nur noch Deine Objekte selbst als [Serializable] kennzeichnen und feddich. :D
    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!

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „RodFromGermany“ ()

    Vielleicht ein wenig OT, aber: Was genau hat die Verwendung von dem Attribut für Vorteile?

    Was ich anerkenne, ist wenn man etwas NICHT serialisiert haben will, dann kann man ja NoSerialize hinschreiben. Doch was bring Serialize? In Json kann man ja wenigstens noch definieren, wie die Knoten heißen, wenn man sie serialisiert.

    Lg Radinator
    In general (across programming languages), a pointer is a number that represents a physical location in memory. A nullpointer is (almost always) one that points to 0, and is widely recognized as "not pointing to anything". Since systems have different amounts of supported memory, it doesn't always take the same number of bytes to hold that number, so we call a "native size integer" one that can hold a pointer on any particular system. - Sam Harwell

    MSDN schrieb:

    Apply the SerializableAttribute attribute to a type to indicate that instances of this type can be serialized. The common language runtime throws SerializationException if any type in the graph of objects being serialized does not have the SerializableAttribute attribute applied.

    Das genügt mir als Erklärung.
    Hier mehr:
    msdn.microsoft.com/en-us/libra…eattribute(v=vs.110).aspx