qb64

Segmentation fault issue using the QB64 function SWAP with user-defined types


I was trying to compile the QB program DIMORDIN.BAS (an example contained into the old QB4.5 package) using QB64 V1.2.

The compilation doesn't indicate errors, but the execution of the program shown a surprise ... The execution of the most of sort types result in a segmentation fault.

Debugging the code I discovered that the cause of this result is the language function SWAP that, on evidence, is not able to swap complex and/or user defined types. Lines such this: SWAP MatrOrd(Riga), MatrOrd(Riga + Scarto) gives segmentation fault.

Have you a solution? Why is QB64 not compliant with this feature of QB4.5?

The following code is the original code of a SUB that gives segmentation fault(unluckely I've only the italian version).

I cannot post here the full code because it's greater than 30,000 chars.

SUB OrdShell STATIC

    ' Imposta lo scarto per il confronto a met del numero di record in MatrOrd:
    Scarto = RigheMass \ 2

    PRINT
    DO WHILE Scarto > 0 ' Cicla finch Scarto non diventa zero.
        Limite = RigheMass - Scarto
        DO
            Scambi = FALSO ' Presume non vi siano stati scambi
            ' con questo valore di Scarto.

            ' Confronta elementi e scambia quelli non in ordine:
            FOR Riga = 1 TO Limite
                IF MatrOrd(Riga).Lung > MatrOrd(Riga + Scarto).Lung THEN
                    SWAP MatrOrd(Riga), MatrOrd(Riga + Scarto)
                    ScambiaBarre Riga, Riga + Scarto
                    Scambi = Riga
                END IF
            NEXT Riga

            ' Al passaggio successivo ordina solo fino al punto dell'ultimo
            ' scambio:
            Limite = Scambi - Scarto
        LOOP WHILE Scambi

        ' Nessuno scambio al precedente valore di scarto; lo dimezza:
        Scarto = Scarto \ 2
    LOOP
END SUB

To help you understanting the SUB I add the declarative portion of the program:

' Definisce il tipo di dati usato per contenere i dati delle barre:
TYPE TipoOrd
    Lung AS INTEGER ' Lunghezza della barra (l'elemento di
    ' confronto nei vari ordinamenti)
    ValColore AS INTEGER ' Colore della barra
    StringaBarra AS STRING * 43 ' La barra (una stringa di 43 caratteri)
END TYPE

' Dichiara le costanti globali:
CONST FALSO = 0, VERO = NOT FALSO, COLONNASIN = 49
CONST NUMOPZIONI = 11, NUMORDINAMENTI = 6

' Dichiara le variabili globali e alloca loro spazio nella memoria. MatrOrd
' e BackupOrd sono matrici del tipo di dati TipoOrd definito sopra:
DIM SHARED MatrOrd(1 TO 43) AS TipoOrd, BackupOrd(1 TO 43) AS TipoOrd
DIM SHARED LeggendaOpzioni(1 TO NUMOPZIONI) AS STRING * 14
DIM SHARED TempoIniz AS SINGLE
DIM SHARED PrimoPiano, Sfondo, Silenzio, Pausa
DIM SHARED Selezione, RigheMass, RigheIniz, ColoriMass

I've written the following small code to demonstrate the issue that the function SWAP generates:

$CONSOLE:ONLY
_DEST _CONSOLE

TYPE TipoOrd
    Lung AS INTEGER ' Lunghezza della barra (l'elemento di
    ' confronto nei vari ordinamenti)
    ValColore AS INTEGER ' Colore della barra
    StringaBarra AS STRING * 43 ' La barra (una stringa di 43 caratteri)
END TYPE

DIM a(1 TO 43) AS TipoOrd

a(1).Lung = 2: a(2).Lung = 4
PRINT a(1).Lung, a(2).Lung
SWAP a(1), a(2)
PRINT a(1).Lung, a(2).Lung

END

Solution

  • I have written this QB64 v1.3a code for swapping structures with some success:

    TYPE Struct1
        Element1 AS INTEGER
        Element2 AS INTEGER
    END TYPE
    DIM SHARED StructA(10) AS Struct1
    DIM SHARED StructB(10) AS Struct1
    StructA(1).Element1 = -1
    StructB(1).Element1 = 1
    PRINT "StructA="; StructA(1).Element1
    PRINT "StructB="; StructB(1).Element1
    PRINT "Swap:"
    SWAP StructA(1), StructB(1)
    PRINT "StructA="; StructA(1).Element1
    PRINT "StructB="; StructB(1).Element1
    END