none
Array wird nicht Richtig Dimensioniert.... RRS feed

  • Frage

  • Hallo ich habe mal wieder was "Lustiges" gemacht,

    ich definiere mir unter anderem drei Array in der Form
    Dim Segment as Integer = 64
    
    
    
    Dim Reverenc_array(Segmente) As Integer
    
    Dim OnTimeingArray(Segmente) As Integer
    
    Dim OffTimeingArray(Segmente) As Integer
    
    
    
    ...
    
    'weiter unten in einer Sub dann Array Füllen 
    
     For Each Load_String In arrText
    
                OnTimeingArray(Counter) = CInt(Load_String)
    
                        Me.BeginInvoke(New StringSubPointer(AddressOf Display), Str(OnTimeingArray(Counter)))
    
                        Counter += 1
    
    Next
    
    
    
    
    
    
    Das  Reverenc_array ist auch 64 Elementen groß die anderen beiden nur leider nicht. Im DebugModus haben die beiden eine Länge von 1. Hat jemand eine Idee wo mein Fehler ist?? Wenn ich die 64 fest rein Code dann stimmen die größen der beiden Arrays.
    Mittwoch, 17. Februar 2010 14:36

Antworten

  • Hallo,

    Nein, ein Visual Basic Express liegt es nicht. Die Compiler sind überall gleich
    und Arrays werden von .NET erzeugt (sind also sogar sprachenunabhängig).

    Es wird etwas nicht mit Deiner Initialisierung stimmen.
    Wo werden die Arrays überhaupt deklariert:
    In einer Klasse oder in einem Modul?
    Stehen die Deklarationen zusammen oder sind sie verstreut?
    Denn vermutlich werden die beiden einstelligen Arrays zu einem Zeitpunkt definiert,
    wo Segmente den Wert 0 hat, was ein Array(0) ergibt.

    Aber wie heißt es so schön:
    Wenn man nicht mehr durch eine Klasse durchblickt sollte man sie aufteilen.

    Zwei Vorschläge - je nach effektiver Nutzung mag der zweite der bessere sein oder nicht:
    Entweder erstellst Du eine eigene Klasse für die Arrays, z. B.:
    Public Class SegmenteCollection
        Private Const SegmenteDefault As Integer = 64
        Private _segmente As Integer
        Private _reverenc() As Integer
        Private _onTimeing() As Integer
        Private _offTimeing() As Integer
    
        Public Sub New()
            Me.New(SegmenteDefault)
        End Sub
        Public Sub New(ByVal segmente As Integer)
            Me.Resize(segmente)
        End Sub
    
        Public Property Segmente() As Integer
            Get
                Return Me._segmente
            End Get
            Set(ByVal value As Integer)
                Me.Resize(value)
            End Set
        End Property
    
        Private Sub Resize(ByVal segmente As Integer)
            If segmente <= 0 Then
                Throw New ArgumentOutOfRangeException()
            End If
            Me._segmente = segmente
            ReDim Preserve _reverenc(segmente)
            ReDim Preserve _onTimeing(segmente)
            ReDim Preserve _offTimeing(segmente)
        End Sub
    
        Public ReadOnly Property Reverenc() As Integer()
            Get
                Return _reverenc
            End Get
        End Property
    
        Public ReadOnly Property OnTimeing() As Integer()
            Get
                Return _onTimeing
            End Get
        End Property
    
        Public ReadOnly Property OffTimeing() As Integer()
            Get
                Return _offTimeing
            End Get
        End Property
    End Class
    
    Ich habe die (denglischen) Variablen bis auf das überflüssige Array so gelassen.
    Die Verwendung wäre dann in etwa:
            Segmente.OffTimeing(0) = 4711
            Segmente.OnTimeing(1) = 4712
            Segmente.Reverenc(Segmente2.Segmente - 1) = 4713
    		
    	Segmente.Segmente = 100 ' Neue Größe
    		
    Oder Du erstellst eine eigene Struktur/Klasse - was sich vor allem empfiehlt,
    wenn die 3 Werte immer (häufig) zusammen verwendet werden:

    Public Structure Segment
        Private _reverence As Integer
        Private _onTimeing As Integer
        Private _offTimeing As Integer
    
        Public Property Reverenc() As Integer
            Get
                Return Me._reverence
            End Get
            Set(ByVal value As Integer)
                Me._reverence = value
            End Set
        End Property
    
        Public Property OnTimeing() As Integer
            Get
                Return Me._onTimeing
            End Get
            Set(ByVal value As Integer)
                Me._onTimeing = value
            End Set
        End Property
    
        Public Property OffTimeing() As Integer
            Get
                Return Me._offTimeing
            End Get
            Set(ByVal value As Integer)
                Me._offTimeing = value
            End Set
        End Property
    End Structure
    
    
    Was Du auch als Array verwenden kannst:
            Dim Segmente(64) As Segment
    
    oder aber als Auflistung
         Dim Segmente As new List(Of Segment)
    verwenden kannst. Bei letzterem bis brauchst Du kein Größe mehr angeben,
    allerdings mußt Du den bisherigen Code für die Zuweisung ändern.

    Gruß Elmar
    Donnerstag, 18. Februar 2010 08:45

Alle Antworten

  • Hi,

    also der erste Bug ist, dass Du "Segment" als Zählvariable deklarierst, aber bei der Dimensionierung der Arrays "Segmente " benutzt... Vielleicht liegt's ja schon daran...

    Gruß
    Marcus
    Mittwoch, 17. Februar 2010 16:43
  • Hallo,

    vorausgesetzt es heißt Dim Segmente As Integer = 64
    und es treibt sich nicht eine Variable Segment (mit 1) herum:

    Erzeugt wird das Array mit dem Wert den die Variable Segmente zum Zeitpunkt
    der Erstellung hat. Und das wären hier 65 (nicht 64) Integer, da Visual Basic
    den Wert als Obergrenze verwendet, siehe Arrays in Visual Basic

    Ergo: Vermutlich ändert sich irgendwo Segment(e).

    Falls Du immer 64 (oder 65) Elemente brauchst, wäre es sinnvoller
    Segmente als eine Konstante (Const ) zu definieren. Dann werden
    Änderungen als Fehler ausgeworfen (was Du hier auch zum Suchen
    nach - irrtümlichen - Änderungen nutzen kannst).

    Gruß Elmar
    Mittwoch, 17. Februar 2010 16:55
  • Servus, das mit dem e und nicht e ist ein Fehler hier, im Code ist es nicht so. Die zuweisung des Werts 64 kommt beim Programmstart aus einer XML Datei, also fällt das mit der Konstanten leider Flach.
    Mittwoch, 17. Februar 2010 20:29
  • Hallo,

    der gezeigte Codeausschnitt gibt sonst nichts her, was den Fehler erklären würde.

    Gruß Elmar
    Mittwoch, 17. Februar 2010 21:10
  • Hi,
    an andere Stelle gibt es keine Verwendung der Arrayas auser wie oben geschreiben und die Restlichen 1300 Zeilen zu Posten ist mach die sache nicht übersichtlicher :-( 
    Es ist halt Komisch das im Debugmodus zwar Segmente mit 64 Angegeben wird, auch in der Arraydefinition wird Segmente mit 64 Angezeigt aber die größe/länge des Arrays hat dann doch nur 1. 
    Es gibt doch aber keine Codebeschränkung in der ExpressVersion oder? 
    • Bearbeitet EL_loro Donnerstag, 18. Februar 2010 18:12
    Mittwoch, 17. Februar 2010 22:45
  • Hallo El_loro,

    kann ich ehrlich gesagt auch nicht nachvollziehen; das funktioniert tadellos und ich habe es auch extra in der Express Edition getestet.
    Wie / wo lässt Du Dir den die Größe des Arrays anzeigen? Läuft die Routine auf einen Fehler, wenn Du das 64te Element schreiben willst (wie unten)?

    Module Module1

     

        Sub Main()

            Dim Segment As Integer = 64

            Dim Reverenc_array(Segment) As Integer

            Dim OnTimeingArray(Segment) As Integer

            Dim OffTimeingArray(Segment) As Integer

     

            Console.WriteLine(String.Format("Von {0} bis {1}", _

                                             Reverenc_array.GetLowerBound(0), _

                                             Reverenc_array.GetUpperBound(0)))

            Console.WriteLine(String.Format("Von {0} bis {1}", _

                                            OnTimeingArray.GetLowerBound(0), _

                                            OnTimeingArray.GetUpperBound(0)))

            Console.WriteLine(String.Format("Von {0} bis {1}", _

                                            OffTimeingArray.GetLowerBound(0), _

                                            OffTimeingArray.GetUpperBound(0)))

     

            Try

                Reverenc_array(64) = 64

                OnTimeingArray(64) = 64

                OffTimeingArray(64) = 64

     

                Console.WriteLine("Geht")

            Catch ex As Exception

                Console.WriteLine(ex.Message)

            End Try

     

            Console.ReadKey()

        End Sub

     

    End Module


    Olaf Helper ----------- * cogito ergo sum * errare humanum est * quote erat demonstrandum * Wenn ich denke, ist das ein Fehler und das beweise ich täglich http://olafhelper.over-blog.de
    Donnerstag, 18. Februar 2010 07:19
  • Hi,

    Werden die 3 Arrays denn, wie bei dir oben wirklich jeweils in der nächsten Zeile schon deklariert? Oder sind da noch Zeilen dazwischen?

    mfg
    Imperium_Romanum
    MAY THE SOURCE BE WITH YOU!
    Donnerstag, 18. Februar 2010 08:40
  • Hallo,

    Nein, ein Visual Basic Express liegt es nicht. Die Compiler sind überall gleich
    und Arrays werden von .NET erzeugt (sind also sogar sprachenunabhängig).

    Es wird etwas nicht mit Deiner Initialisierung stimmen.
    Wo werden die Arrays überhaupt deklariert:
    In einer Klasse oder in einem Modul?
    Stehen die Deklarationen zusammen oder sind sie verstreut?
    Denn vermutlich werden die beiden einstelligen Arrays zu einem Zeitpunkt definiert,
    wo Segmente den Wert 0 hat, was ein Array(0) ergibt.

    Aber wie heißt es so schön:
    Wenn man nicht mehr durch eine Klasse durchblickt sollte man sie aufteilen.

    Zwei Vorschläge - je nach effektiver Nutzung mag der zweite der bessere sein oder nicht:
    Entweder erstellst Du eine eigene Klasse für die Arrays, z. B.:
    Public Class SegmenteCollection
        Private Const SegmenteDefault As Integer = 64
        Private _segmente As Integer
        Private _reverenc() As Integer
        Private _onTimeing() As Integer
        Private _offTimeing() As Integer
    
        Public Sub New()
            Me.New(SegmenteDefault)
        End Sub
        Public Sub New(ByVal segmente As Integer)
            Me.Resize(segmente)
        End Sub
    
        Public Property Segmente() As Integer
            Get
                Return Me._segmente
            End Get
            Set(ByVal value As Integer)
                Me.Resize(value)
            End Set
        End Property
    
        Private Sub Resize(ByVal segmente As Integer)
            If segmente <= 0 Then
                Throw New ArgumentOutOfRangeException()
            End If
            Me._segmente = segmente
            ReDim Preserve _reverenc(segmente)
            ReDim Preserve _onTimeing(segmente)
            ReDim Preserve _offTimeing(segmente)
        End Sub
    
        Public ReadOnly Property Reverenc() As Integer()
            Get
                Return _reverenc
            End Get
        End Property
    
        Public ReadOnly Property OnTimeing() As Integer()
            Get
                Return _onTimeing
            End Get
        End Property
    
        Public ReadOnly Property OffTimeing() As Integer()
            Get
                Return _offTimeing
            End Get
        End Property
    End Class
    
    Ich habe die (denglischen) Variablen bis auf das überflüssige Array so gelassen.
    Die Verwendung wäre dann in etwa:
            Segmente.OffTimeing(0) = 4711
            Segmente.OnTimeing(1) = 4712
            Segmente.Reverenc(Segmente2.Segmente - 1) = 4713
    		
    	Segmente.Segmente = 100 ' Neue Größe
    		
    Oder Du erstellst eine eigene Struktur/Klasse - was sich vor allem empfiehlt,
    wenn die 3 Werte immer (häufig) zusammen verwendet werden:

    Public Structure Segment
        Private _reverence As Integer
        Private _onTimeing As Integer
        Private _offTimeing As Integer
    
        Public Property Reverenc() As Integer
            Get
                Return Me._reverence
            End Get
            Set(ByVal value As Integer)
                Me._reverence = value
            End Set
        End Property
    
        Public Property OnTimeing() As Integer
            Get
                Return Me._onTimeing
            End Get
            Set(ByVal value As Integer)
                Me._onTimeing = value
            End Set
        End Property
    
        Public Property OffTimeing() As Integer
            Get
                Return Me._offTimeing
            End Get
            Set(ByVal value As Integer)
                Me._offTimeing = value
            End Set
        End Property
    End Structure
    
    
    Was Du auch als Array verwenden kannst:
            Dim Segmente(64) As Segment
    
    oder aber als Auflistung
         Dim Segmente As new List(Of Segment)
    verwenden kannst. Bei letzterem bis brauchst Du kein Größe mehr angeben,
    allerdings mußt Du den bisherigen Code für die Zuweisung ändern.

    Gruß Elmar
    Donnerstag, 18. Februar 2010 08:45
  • Servus,
    die Arrays werden direkt hintereinander Deffiniert in einer Klasse. Ich werde es mal mit Elmar's Ansatz Probieren und Alle Arrays in einer neue Klasse verschieben.. Mal schauen...

    Es kracht schon wenn ich den zweiten Wert reinschieben will allso array(1) = irgend_eine_zahl. 

    Aber Schon mal danke für eure Hilfe.

    Gruß Loro

    Donnerstag, 18. Februar 2010 14:35
  • Hi,

    Hast du die Dimensionierungen vielleicht in einem Try-Catch-Block? Sodass evtl. das erste Array noch richtig dimensioniert wird, dann aber eine Stack-Overflow-Exception o.ä. auftritt und das Programm einfach wo anders weitermacht.

    mfg
    Imperium_Romanum
    MAY THE SOURCE BE WITH YOU!
    Samstag, 20. Februar 2010 11:32