Sortieren eines Adressbereichs (qsort)
-
Hallo,
ein Adressbereich soll aus einem COBOL-Programm durch Aufruf eines C-Programms sortiert werden.
Leider kommt momentan die folgende Fehlermeldung:
Execution error : file 'XXX'
error code: 114, pc=0, call=1, seg=0
114 Attempt to access item beyond bounds of memory (Signal 11)Kann mir jmd. das C-Programm verbessern? Beim qsort ist ein Fehler (entweder beim Aufruf oder in der Sortierfunktion vergleich). Wie kann man Adressbereiche mit qsort sortieren?
#include <stdio.h> #include <stdlib.h> #include <string.h> static int g_laenge_key, g_anfang_key; // Vergleichsfunktion für Quicksort und binäre Suche // vergleicht Zeichenketten int vergleich(const void *a, const void *b) { const char **ia = (const char **)a; const char **ib = (const char **)b; return strncmp(*ia+g_anfang_key,*ib+g_anfang_key,g_laenge_key); } extern void TEST44 ( int *anzahl_saetze, // Anzahl Sätze int *laenge_key, // Länge Sortierbegriff int *anfang_key, // Beginn Sortierbegriff int *laenge_satz, // Länge Satz char *beginnadresse_tabelle // Beginnadresse Tabelle ) { int i; g_laenge_key = *laenge_key; g_anfang_key = *anfang_key; /* // Liste zum ersten Mal ausgeben printf("\nListe vorher: \n"); for(i = 0; i < *5; i++) printf("%p\n", *(beginnadresse_tabelle+i)); */ // Liste sortieren qsort(( char * ) beginnadresse_tabelle, *(anzahl_saetze), sizeof(*laenge_satz), vergleich); /* // Liste zum zweiten Mal ausgeben printf("\nListe nachher: \n"); for(i = 0; i < *5; i++) printf("%p\n", *(beginnadresse_tabelle+i)); */ }
-
wie sieht deine tabelle aus? du brauchst ein array.
-
Wie ist denn deine Tabelle im Speicher aufgebaut?
Erst ein key, dann der Datensatz usw. oder nur keys, die jeweils einen Zeiger auf den Datensatz darstellen?
Sind die Daten C-Strings ( '\0' terminiert )?
-
Kann man aus COBOL überhaupt Funktionen aus C aufrufen und wie sehen da Funktionsaufrufe aus? Diese müssen schon der C-Konvention genügen!
-
berniebutt schrieb:
Kann man aus COBOL überhaupt Funktionen aus C aufrufen und wie sehen da Funktionsaufrufe aus? Diese müssen schon der C-Konvention genügen!
Déjà-vu, es hat schon mal geklappt: Teilstrings sortieren
-
sizeof(*laenge_satz)?!
Wie sehen die übergebenen Parameter denn in COBOL-Picturing aus?
-
Die übergebenen Parameter in COBOL-Picturing:
V-TEST44-ANZAHL-TAB PIC S9(8) BINARY SYNC. V-TEST44-LG-KEY PIC S9(8) BINARY SYNC. V-TEST44-ANFANG-KEY PIC S9(8) BINARY SYNC. V-TEST44-LG-SATZ PIC S9(8) BINARY SYNC. DRNR-SC-ST-1 PIC X(1)
Und der Aufruf des C-Programms in COBOL:
068800 W99-CALL-TEST44 SECTION. SE41 400 069800 W9900. SE41 400 DISPLAY 'X41E - DRNR-01 vorher:' DRNR1-SATZ (1) DISPLAY 'X41E - DRNR-02 vorher:' DRNR1-SATZ (2) SET DRNR1-LG-VAR-WERT TO TRUE . 132700 MOVE DRNR1-ZL-VAR-MAX TO V-TEST44-ANZAHL-TAB MOVE 18 TO V-TEST44-LG-KEY MOVE 5 TO V-TEST44-ANFANG-KEY MOVE DRNR1-LG-VAR TO V-TEST44-LG-SATZ 488600 CALL 'TEST44' USING 132700 V-TEST44-ANZAHL-TAB V-TEST44-LG-KEY V-TEST44-ANFANG-KEY V-TEST44-LG-SATZ 488700 DRNR-SC-ST-1 (1) . DISPLAY 'X41E - DRNR-01 nachher:' DRNR1-SATZ (1) DISPLAY 'X41E - DRNR-02 nachher:' DRNR1-SATZ (2). 070100 W9999. SE41 400 070200 EXIT. SE41 400
Die Tabelle sieht wie folgt aus (Ausschnitt):
DRNR PM -NA FQ-NR AANR ATAA ATEL KTAN FORM SORT MM ABW MM-POSE LOGO DRUCKART POSE-SAM-FRIST KOPIEN DURCHSCHRIFT PPAT
0135 #0135 00 0224 0 0 ## 0135 04 000 0 0 0 00 00 0 0
0139 #0139 00 0601 0 5 0139 02 000 0 0 0 00 00 0 0
0139 #0139 00 0603 6 5 0139 02 000 0 0 0 00 00 0 0
0146 #0146 00 0820 1 1 0146 03 000 0 0 0 00 00 0 0
0146 #0146 00 0810 0 1 0146 15 000 0 0 0 00 00 0 0
0146 #0146 00 0820 0 1 0146 15 000 0 0 0 00 00 0 0
0205 #0205 00 0601 0 3 0205 16 000 0 0 0 00 00 0 0
0205 #0205 00 0601 0 4 0205 16 000 0 0 0 00 00 0 0
0205 #0205 00 0601 0 5 0205 16 000 0 0 0 00 00 0 0
0205 #0205 00 0603 0 3 0205 16 000 0 0 0 00 00 0 0
0205 #0205 00 0603 0 4 0205 16 000 0 0 0 00 00 0 0
0205 #0205 00 0603 0 5 0205 16 000 0 0 0 00 00 0 0
0205 #0205 00 0603 2 3 0205 16 000 0 0 0 00 00 0 0
0205 #0205 00 0603 2 4 0205 16 000 0 0 0 00 00 0 0
0205 #0205 00 0603 2 5 0205 16 000 0 0 0 00 00 0 0
0205 #0205 00 0603 6 3 0205 16 000 0 0 0 00 00 0 0In der Tabelle ist dann ab Stelle 5, 18 Stellen lang zu sortieren und das
mit max. 15.000 Elementen. Weiß jmd., welche Änderung im qsort zu machen sind bzw. in der Funktion vergleich?
-
#include <stdio.h> #include <stdlib.h> #include <string.h> static int g_laenge_key, g_laenge_satz; // Vergleichsfunktion für Quicksort und binäre Suche // vergleicht Zeichenketten int vergleich(const void *a, const void *b) { const char *x = a; const char *y = b; return memcmp(x+g_laenge_key,y+g_laenge_key,g_laenge_satz); } /* das extern ist hier falsch, sollte export oder was passendes aus dem Compilerangebot sein */ extern void TEST44 ( int *anzahl_saetze, // Anzahl Sätze int *laenge_key, // Länge Sortierbegriff int *anfang_key, // Beginn Sortierbegriff int *laenge_satz, // Länge Satz char *beginnadresse_tabelle // Beginnadresse Tabelle ) { int i; g_laenge_key = *laenge_key; g_laenge_satz = *laenge_satz; // Liste zum ersten Mal ausgeben printf("\nListe vorher: \n"); for(i = 0; i < anzahl_saetze; i++) fwrite(beginnadresse_tabelle+i*(g_laenge_key+g_laenge_satz)+g_laenge_key,g_laenge_satz,1,stdout),puts(""); // Liste sortieren qsort(beginnadresse_tabelle, *anzahl_saetze,g_laenge_key+g_laenge_satz, vergleich); // Liste zum zweiten Mal ausgeben printf("\nListe nachher: \n"); for(i = 0; i < anzahl_saetze; i++) fwrite(beginnadresse_tabelle+i*(g_laenge_key+g_laenge_satz)+g_laenge_key,g_laenge_satz,1,stdout),puts(""); }
Geht davon aus, dass jedes "Tabellen"-Element genau g_laenge_key+g_laenge_satz Zeichen/Bytes lang ist und dass nach genau g_laenge_satz Zeichen/Bytes "aufsteigend" sortiert wird. (in deinem Kommentar steht aber, dass nach key sortiert wird?!)
Versuche erstmal, die Testausgaben richtig hinzubekommen, das qsort kann dann später kommen.
-
Danke Wutz.
Zu deiner Frage: Ja, es wird nach Key sortiert. laenge_satz beinhaltet den
kompletten Satz. Ab Stelle 5 (anfang_key) werden dann die 18 nachfolgenden Stellen (laenge_key) sortiert. Bsp.: 0135#013500022400## 013504000000000000
=> sortiert werden soll nach #013500022400Das mit dem extern für den externen Aufruf von C-Programmen ist korrekt.
Evtl. Problem: anzahl_saetze ist variabel (max. 15.000). Klappt die Sortierung evtl. deshalb nicht?
Mein aktuelles Programm sieht jetzt so aus:
#include <stdio.h> #include <stdlib.h> #include <string.h> static int g_laenge_key, g_anfang_key; static int g_laenge_satz; // Vergleichsfunktion für Quicksort und binäre Suche // vergleicht Zeichenketten int vergleich(const void *a, const void *b) { const char *ia = (const char *)a; const char *ib = (const char *)b; return memcmp(ia+g_anfang_key,ib+g_anfang_key,g_laenge_key); } extern void TEST44 ( int *anzahl_saetze, // Anzahl Sätze int *laenge_key, // Länge Sortierbegriff int *anfang_key, // Beginn Sortierbegriff int *laenge_satz, // Länge Satz char *beginnadresse_tabelle ) { int i; g_laenge_key = *laenge_key; g_anfang_key = *anfang_key; g_laenge_satz = *laenge_satz; printf("\nAnzahl Sätze: %d\n", *anzahl_saetze); printf("\nLänge Sortierbegriff: %d\n", *laenge_key); printf("\nBeginn Sortierbegriff: %d\n", *anfang_key); printf("\nLänge Satz: %d\n", *laenge_satz); printf("\nTest_15_40\n"); // Liste zum ersten Mal ausgeben printf("\nListe vorher: \n"); for(i = 0; i < 5; i++) fwrite(beginnadresse_tabelle+i*(g_laenge_satz),g_laenge_satz,1,stdout),puts(""); // Liste sortieren qsort(beginnadresse_tabelle, *(anzahl_saetze), sizeof(*laenge_satz), vergleich); // Liste zum zweiten Mal ausgeben printf("\nListe nachher: \n"); for(i = 0; i < 5; i++) fwrite(beginnadresse_tabelle+i*(g_laenge_satz),g_laenge_satz,1,stdout),puts(""); }
Ausgabe ist allerdings:
X41E - DRNR-01 vorher:0135#013500022400## 013504000000000000
X41E - DRNR-02 vorher:0139#013900060105## 013902000000000000Anzahl Sätze: 15000
Länge Sortierbegriff: 18
Beginn Sortierbegriff: 5
Länge Satz: 67
Test_15_40
Liste vorher:
0135#013500022400## 013504000000000000
0139#013900060105## 013902000000000000
0139#013900060365## 013902000000000000
0146#014600081001## 014615000000000000
0146#014600082001## 014615000000000000Liste nachher:
000
X41E - DRNR-01 nachher:00
X41E - DRNR-02 nachher:
-
Nein, extern ist hier nicht richtig.
Du hast nicht verstanden, was extern ist. extern mit einer Definition verbunden wie bei dir ist Unsinn und JW-Pfusch Niveau.
Auch den qsort Aufruf hast du geändert, dann brauchst du dich nicht zu wundern, wenn es nicht läuft.
Gehe davon aus, dass qsort fehlerfrei implementiert ist, auch 15000 Sätze sind neben dem Zeitfaktor kein Problem.
-
sorry wutz, du hast natürlich recht. Bin halt noch nicht bei 1.500 Forenbeiträgen
Nachdem ich den qsort Aufruf und die vergleich-Funktion exakt so umgesetzt habe (wie in deinem Beitrag) funktioniert die Sortierung 3. Parameter abgeändert und (const char
in der vergleich-Funktion weggelassen. Und auch das mit dem extern (nur zu verwenden bei einer Deklaration) stimmt. Meine Vorlage war falsch