Auslesen Eines Arrays: fehlerhafte Werte



  • Hallo Leute!

    Ich schreibe momentan ein Programm zur Berechnung von Passungen für den Metallbereich. In Excel läuft das Ding schon. Aus Sicherheitsgründen
    (Manipulatiossicherheit) und der Portierbarkeit will ich es in C++
    umschreiben. Da ich selbst als Messtechniker schon welche erlebt habe,
    die vorsätzlich andere Zahlen reinschrieben oder Messgeräte manipulierten,
    skalen verdrehten usw.
    Aber ich kennt das sicher. Dem will ich einen Riegel vorschieben.
    Die Werte kommen später als Konstanten in ein zweidimensionales Array
    und werden dort für die Berechnungen ausgelesen. Das Array ist Einheitswelle[41][33];

    Ab Einheitswelle[15][1];
    

    liefert die Funktion falsche Werte.
    Ich arbeite mit codeblocks 13.12 und Suse Linux Leap 42.1.

    int getwellebeginn(double nennmass, int suchspalte, short welle[41][33])
    {
    short zeile;
    short ug, og, rewer = -1;
    cout << "\nGetwellebeginn:\n";
    for (zeile = 0; zeile < 41; zeile++)
     {
      ug = welle[zeile][0];
      og = welle[zeile][1];
      //cout <<"\nug "<< ug << "og" << og;
    
      if ((nennmass > ug) && (nennmass <= og))
      {
       rewer = welle[zeile][suchspalte + 2];
       //cout <<"\nug=" << ug << "   og="<< og << "    wert=" << rewer <<  " suchspalte=" << suchspalte << " zeile=" <<zeile << endl;
       break;
      }
     }
    
    return rewer;
    }
    

    Die Ausgabezeilen dienen zu Fehlersuche. Kann das sein, das das Array zu groß ist(Speicherverwaltung)für diese Art der Initialisierung;
    Eine einstellung für den Heap habe ich in der IDE nicht gefunden. Gibt es noch
    einen Weg, anstatt das Array aufzuteilen? Ein weiteres array ITTolerances[22][22] läuft einwandfrei, geplant ist noch ein weiteres Array.



  • Hallo rustyoldguy,

    ich habs noch nicht so wirklich verstanden, wo der Fehler/das Problem liegt.
    Du sagst nur da passt was nicht, aber das was nicht passt finde ich in Deinem Codeabschnitt nicht wieder. Übersehe ich gerade was?

    int myarray[5];
    

    Das wird auf dem Stack abgelegt und nicht auf dem Heap.

    Für die Heap-Allokation benötigt man den new Operator.
    Beispiel:

    int* myarray = new int[5];
    
    myarray[0] = 123;
    

    Initialisierung vom Speicher nicht vergessen.

    Was die Heapgröße angeht, die maximale Größe ist Dein Arbeitsspeicher, Stackgröße ist meines Wissens CPU abhängig.

    Viele Grüße,

    Jakob

    ---

    edit: Schau dir mal die STL Container Klassen an wie den std::vector -> http://www.cplusplus.com/reference/stl/



  • jb schrieb:

    Stackgröße ist meines Wissens CPU abhängig.

    Falsch.

    Zu groß ist das Array sicher nicht. Aber rohe Arrays sind in C++ ziemlich fehleranfällig. Ich müsste auch erst überlegen, wie man das richtig macht (auch, weil ich das noch nie gemacht habe). Benutz einen std::vector oder eine eigene Datenstruktur, die den vector oder ähnliche Container kapselt.



  • Das Programm klappt jetzt.

    Nach dem Gegenlesen wurde ein Komma übersehen, so das sich die Werte beim Initialisieren verschoben hatten. Handeingabe, da
    kein gutes Freeware-OCR-Programm für Suse-Linux! Da hätte ich die OCR-Ergebnisdateienmehr
    korrigiert, als das ganze Scannen wert ist!

    By the way, wie bringe ich eigentlich ein solches
    Monster-Array eigentlich in eine Klasse beim initialisieren?

    Auf meine Recherchen bei verschiedenen Autoren habe ich nichts gefunden, wie
    ein zweidimensionales Array innerhalb einer Klasse beim Konstruktor
    initialisiert wird, oder ist es besser, das ganze gleich in eine Include-Datei
    zu legen? die Gesamtzahl aller Werte ist 3343. Ich denke das eine Änderung der DIN ISO 286-1 sowie der DIN ISO 296-2
    (Passungsberechnungen für Außen- und Innenmaße) wohl noch längere Zeit, wenn überhaupt auf sich warten lässt, eine Deklaration
    als const in einer include-Datei würde sich eher anbieten.
    Zudem sind ja die Werte an die Schulungsunterlagen gebunden, die ich beim Kursus zum DGQ-Qualitätsassistenten- und Fachkraft sowie
    Messtechnik bekam.
    Gelänge es mir diese innerhalb einer Klasse zu verbergen, bliebe
    das Copyright unverletzt. Geplant ist eine Programmversion für
    Umschüler, als Lernhilfe.

    Wie denkt Ihr darüber?



  • Mechanics schrieb:

    jb schrieb:

    Stackgröße ist meines Wissens CPU abhängig.

    Falsch.

    Ziemlich einsilbig. Was ist den korrekt?



  • Die Stackgröße kannst du in den Linkereinstellungen setzen.



  • Warum soll er an den stacksettings spielen??? Was hat das mit dem Problem zu tun?



  • Beiträge freuen sich, wenn man sie ließt.



  • rustyoldguy schrieb:

    By the way, wie bringe ich eigentlich ein solches
    Monster-Array eigentlich in eine Klasse beim initialisieren?

    Auf meine Recherchen bei verschiedenen Autoren habe ich nichts gefunden, wie
    ein zweidimensionales Array innerhalb einer Klasse beim Konstruktor
    initialisiert wird, oder ist es besser, das ganze gleich in eine Include-Datei
    zu legen?

    #include ist mMn. schon das richtige Stichwort.
    Du musst Deine Daten halt irgendwie in C++-Syntax dengeln und los. Z.B.

    #include <iostream>
    #include <iterator>
    #include <iomanip>
    
    const double data[20][13]=
      {
        #include "EihWe.data"
      };
    
    int main(){
      for(const auto& z:data){
        for(const auto& t:z)
          std::cout << std::setw(6) << t;
        std::cout << '\n';
      }
    }
    

    Wie Du die Eingabedatei umwandelst ist Dir überlassen - ich habe das auch schon mit Notepad und Word gemacht.

    Aber für den Source von oben mit sed und make .
    Datei EihWe.csv

    0,3 0,4 0,4 0,5 0,6 0,6 0,8 1  1,2 2  2,5 3  4 
    0,5 0,6 0,6 0,8 1  1  1,2 1,5 2  3  4  5  6 
    0,8 1  1  1,2 1,5 1,5 2  2,5 3,5 4,5 6  7  8 
    1,2 1,5 1,5 2  2,5 2,5 3  4  5  7  8  9  10 
    2  2,5 2,5 3  4  4  5  6  8  10  12  13  15 
    3  4  4  5  6  7  8  10  12  14  16  18  20 
    4  5  6  8  9  11  13  15  18  20  23  25  27 
    6  8  9  11  13  16  19  22  25  29  32  36  40 
    10  12  15  18  21  25  30  35  40  46  52  57  63 
    14  18  22  27  33  39  46  54  63  72  81  89  97 
    25  30  36  43  52  62  74  87  100  115  130  140  155 
    40  48  58  70  84  100  120  140  160  185  210  230  250 
    60  75  90  110  130  160  190  220  250  290  320  360  400 
    100  120  150  180  210  250  300  350  400  460  520  570  630 
    140  180  220  270  330  390  460  540  630  720  810  890  970 
    250  300  360  430  520  620  740  870  1000  1150  1300  1400  1550 
    400  480  580  700  840  1000  1200  1400  1600  1850  2100  2300  2500 
    600  750  900  1100  1300  1600  1900  2200  2500  2900  3200  3600  4000 
    1000  1200  1500  1800  2100  2500  3000  3500  4000  4600  5200  5700  6300 
    1400  1800  2200  2700  3300  3900  4600  5400  6300  7200  8100  2200  9700
    

    Makefile:(Zeilen 4 u. 7. beginnen mit einem TAB - nicht mit SPACE)

    CXXFLAGS+=-std=c++14 -Wall -pedantic
    
    %.data : %.csv
    	sed -e 's/,/./g;s/$$/},/g;s/^/{/g;s/[ ]\+/, /g' <$^ >$@
    
    data: data.o
    	$(CXX) $(LDFLAGS) $^ -o $@
    
    data.o : EihWe.data
    


  • Wäre es nicht besser, es als Datei zu speichern?



  • roflo schrieb:

    Wäre es nicht besser, es als Datei zu speichern?

    Mit der executable mitliefern und im Konstruktor auslesen? Vielleicht. Aber dann hätten wir wieder das Ausgangsproblem der manipulierten Tabellen.

    Davon abgesehen finde ich den Weg des direkten einfügens in den Source auch recht gangbar und effizient.
    Natürlich darfst Du neu Kompilieren, sollten sich die Tabellen jemals ändern.



  • Daran habe ich auch schon gedacht. Ich habe mich für die Lösung mit der include-Datei entschieden.

    Das Risiko, das einer die Datei verschlampt oder löscht, ist mir zu groß.
    Ich habe in den Listen der DIN IS0 noch die Nennmaßbereiche mit
    reingepackt, damit eine Selbstkontrolle möglich ist.
    Bei der Masse von Daten habe ich festgestellt, muß der Text für die
    Include-Datei sehr sauber formatiert werden, wegen dem Kontoll-Lesen.
    Würde die Stackgröße nicht stimmen, müßte das Programm diese zur
    Kontrolle ins Array eingepflanzten Werte nicht richtig lesen. Aber
    bei insgesammt 3400 const double-Werten sollte das noch keinen PC
    Schwierigkeiten machen.

    Normalerweise gehen die meisten Tabellenbücher bis 500 mm Nennmaß
    nicht hinaus. Die Toleranzen gehen aber von 1 bis 3150 mm. Einige
    Passungen wie zum Beispiel 27p7 oder 15Z11 stehen in den normalen
    Tabellenbüchern nicht drin. Daher das Programm. Sogar im Internet
    habe ich schon Seiten gefunden, wo diese falsch berechnet werden.
    Das kann bei einer Mängelrüge eines Kunden, bei einer Abweisung
    einer Lieferung ziemlich teuer werden. Komischerweise können sogar
    einige Techniker solche Passungen nicht mit der Hand berechnen.
    Dabei ist das so, wenn man weis wie es geht und die
    Berechnungsunterlagen dazu hat, ist es ganz einfach. Aber wer gibt
    schon mehr als 100 Euro nur für ein Buch zur Passungsberechnung aus.
    Schätze mal, da bin ich einer der wenigen, die so was kaufen(müssen).
    Bei Umschülern zum Qualitätsfachmann für Längenprüftechnik habe ich
    keine Angst vor Fehlbedienung. Dafür ist die Ausbildung bei einem
    BFW viel zu gut. Wohl aber bei beruflichen Seiteneinsteigern(sorry!).
    Deshalb habe ich bei einem anderen Forum absichtlich die EXCEL-Datei
    für Windows gesperrt.


Anmelden zum Antworten