Probleme bei der Kompilierung meines Programms unter Linux



  • wenn ich deinen Code direkt bei

    http://gcc.godbolt.org/

    reinkopieren und mit dem gcc 4.x-6.x oder clang kompilieren Optionen: -O2 -Wall

    kompilierts - und jetzt?

    was ist dein Kompileraufruf: also gcc ... , oder g++ ....



  • Wie startest du das Programm?



  • die -Wall Angabe hat nichts mit deinen Linker-Fehlermeldungen zu tun - wo auch immer du die herbekommst

    zu deinem Speicherzugriffsfehler - du wirst wohl irgendwo ungewollt Speicher überschreiben - das ist "Undefined Behavior" und KANN trotzdem laufen - oder auch abstürzen - wie unter Linux - dein Programm enthält also Fehler

    zu deinem Speicherzugriffsfehler probier mal

    g++ dein_programm.cpp -O -g -fsanitize=address

    und dann ausführen (https://en.wikipedia.org/wiki/AddressSanitizer)



  • dachschaden_off schrieb:

    Mangan2504 schrieb:

    Habe ich versucht, es kommt: not in executable format: File format not recognized
    Ich habe angegeben <programm.cpp> . Wenn ich es ohne .cpp probiere, kommt "Datei oder Verzeichnis nicht gefunden".

    Das Programm, nicht den Sourcecode.

    $ gcc -g -ggdb3 bla.cpp -o bla
    $ ulimit -c unlimited
    $ ./bla
    Segfault (core dumped) <- Oder was ähnliches - muss erscheinen, sonst kannste nicht debuggen
    $ gdb ./bla core
    

    Ja, das erklärt einiges. Ich benutzte wie gesagt sonst nur Code::Blocks, wo man sowas nicht machen muss.

    dachschaden_off schrieb:

    Und wie kommst du dann dazu, Sachen auszuprobieren, die du nicht kannst?

    Leider mache ich in der Hauptsache kein C++, deswegen habe ich auch keine guten Empfehlungen an der Stelle.

    Sicher, dass ein Studium das richtige für dich ist? Und nein, damit impliziere ich nicht, dass du blöd bist. Aber viele Leute kommen mit der Art, wie dort gelehrt wird, nicht zurecht. Darunter gehöre auch ich. Ich muss mir Zeit nehmen, um das, was man mir zeigt, auch zu lernen.

    Oder bist du direkt ohne Vorkenntnisse da reingegangen? Ich finde es immer wieder komisch, wie Leute meinen, im Studium würde ihnen gezeigt werden, wie man programmiert. Sowas bringt man sich aber selbst bei. Eigeninitiative gehört nun mal leider dazu.

    Ok ich will nicht zu viel schwafeln, aber ein bissl was zum besseren Verständnis muss ich dann wohl doch erzälen.
    Ich mache das, weil ich die Prüfung bestehen muss. Es ist so ziemlich das letzte Modul das mir fehlt. Aus sehr vielen Gründen, unter anderem Finanzierung, habe ich leider keine Wahl und kann mir nicht unendlich viel Zeit nehmen.

    Ja, ich bin in diese Veranstaltung ohne Vorkentnisse reingegangen, aber wir hatten schon eine Vorgänger-Veranstaltung dazu, die ich auch schon bestanden habe. Und ja, ich habe gewusst was auf mich zukommt. Es ist nicht so, dass ich dafür nichts mache. Nur leider ist es ja auch so, dass das Studium nicht nur aus dieser einen Veranstaltung besteht.
    Es ist etwas kompliziert zu erklären. Der Studiengang ist neu und generell noch etwas.... unstrukturiert... Es ist auch keine reine Informatik, sondern einer dieser Hybrid-Studiengänge mit Informatik im Nebenfach. Mein prinzipielles Problem ist eigentlich nicht, da einen Algorithmus zu finden mit dem man das lösen könnte, sondern viel eher, aus den einzelnen Fragmenten etwas zu gestalten, dass auch läuft und das macht, was ich will.

    dachschaden_off schrieb:

    stdio.h ist ein C-Header, kein C++-Header. Sowas schreibt man in C-Dateien, keinen CPP-Dateien (je nach Endung behandeln bestimmte Compiler das File dann anders).

    Mist. Die Vorgänger-Veranstaltung war nur C, jetzt machen wir C++. Da bin ich einfach durcheinander geraten.



  • Mangan2504 schrieb:

    Das hier ist das Ergebnis: http://pastebin.com/VxeirRzV

    Das ist eine ganz kaputte Mischung aus C und C++. Ja, mit einem C++-Compiler kompiliert es, aber das ist dennoch C ( fopen , fscanf ...)

    Wenn ich das beim Dozenten gelehrt bekommen hätte, hätte ich ihm erst mal auf den Tisch gekotzt.

    Ich habe jetzt nur nach dem ersten Fehler gesucht, den mir gdb gezeigt hat. Und bin dann darüber gestolpert:

    int main (int x, char *pups[]){
    

    Traditionell sollte das:

    int main(int argc,char*argv[])
    

    sein. Das eigentliche Problem aber ist: du solltest beim Programmaufruf einen Parameter übergeben, der einen Dateinamen beinhaltet, dessen Datei dann später geöffnet werden soll.

    Jetzt haben wir diese Datei allerdings nicht. Blöd gelaufen.

    Und du prüfst auch nicht, ob dein Programm die Datei einladen kann. Blöd gelaufen die zweite.

    if(argc < 2)
    {
        fprintf(stderr,"Nicht genug Argumente: %s <Dateiname>\n",argv[0]);
        return -1;
    }
    
    text = fopen (pups[1], "r");
    if(!text)
    {
        fprintf(stderr,"Datei \"%s\" kann nicht geöffnet werden!\n",pups[1]);
        return -1;
    }
    

    DirkB hat schon nachgefragt, wie rufst du das Programm auf?
    Und ich frage nach der Datei, die du da öffnest.

    Wenn ich übrigens mal die Warnungen anstelle, mit denen ich alles kompiliere, was ich schreibe:

    -W -Wextra -Wall -Wimplicit -Wunused -Wunused-parameter -Wshadow -Wempty-body -Wignored-qualifiers -Wvla -Wvariadic-macros -Wdisabled-optimization -Winline -Wsign-compare -Wuninitialized -Wparentheses -Wswitch
    

    , dann bekomme ich diese Warnungen:

    kata.c: In Funktion »void ausgabe(domino*)«:
    kata.c:43:27: Warnung: Deklaration von »kopf« überdeckt eine globale Deklaration [-Wshadow]
     void ausgabe (domino *kopf){                  // Funktion zum ausgeben einer Liste, soll auch Ringliste ausgeben können
                               ^
    kata.c:16:13: Anmerkung: verdeckte Deklaration ist hier
     verwaltung *kopf, *ende;             // Listenkopf und Listenende erstellen
                 ^
    kata.c: In Funktion »void ausgabeRing(domino*)«:
    kata.c:48:34: Warnung: Deklaration von »ringkopf« überdeckt eine globale Deklaration [-Wshadow]
     void ausgabeRing(domino *ringkopf){
                                      ^
    kata.c:18:9: Anmerkung: verdeckte Deklaration ist hier
     domino *ringkopf, *ringmitte, *ringende; // Ringlistenzeiger (soll nach Ausgabe recyclet werden)
             ^
    kata.c: In Funktion »void bautRing(domino*)«:
    kata.c:58:11: Warnung: Anweisung hat keinen Effekt [-Wunused-value]
         for (n; n != NULL; n = n->next){
               ^
    kata.c: In Funktion »int main(int, char**)«:
    kata.c:96:9: Warnung: Variable »z« wird nicht verwendet [-Wunused-variable]
         int z = 0; // zeigerzähler
             ^
    kata.c: Im globalen Gültigkeitsbereich:
    kata.c:82:15: Warnung: unbenutzter Parameter »x« [-Wunused-parameter]
     int main (int x, char *pups[]){         // pups beinhaltet die Parameter (Anzahl übergebener Werte und Datei)
    

    EDIT: besserer Check, sodass wir den potentiellen NULL-Pointer nicht an fopen übergeben.



  • dachschaden schrieb:

    Das ist eine ganz kaputte Mischung aus C und C++. Ja, mit einem C++-Compiler kompiliert es, aber das ist dennoch C ( fopen , fscanf ...)

    Wenn ich das beim Dozenten gelehrt bekommen hätte, hätte ich ihm erst mal auf den Tisch gekotzt.

    Wie gesagt haben wir in der Vorgänger-Veranstaltung nur mit C programmiert, deswegen ist der Fehler da eher bei mir zu suchen.

    Gast3 schrieb:

    wenn ich deinen Code direkt bei

    http://gcc.godbolt.org/

    reinkopieren und mit dem gcc 4.x-6.x oder clang kompilieren Optionen: -O2 -Wall

    kompilierts - und jetzt?

    was ist dein Kompileraufruf: also gcc ... , oder g++ ....

    Ok? Das ist komisch.

    Wir sollen g++ verwenden.

    In der Anleitung steht:

    Beispiel (Übersetzen des Quellcodes einer Datei „test.cpp“)
    g++ -o test test.cpp

    Ich gebe also ein: g++ -o programm programm.cpp
    auf dem Terminal unter Linux.

    Wenn es laufen würde, dann mache ich weiter mit ./programm.cpp



  • Wenn es laufen würde, dann mache ich weiter mit ./programm.cpp

    nein machst du nicht sondern mit ./programm (nicht .cpp) - die erste Angabe von "programm" in der Kommandozeile sagt wie die Applikation heissen soll

    btw: die vorherigen Post haben den Fehler schon eingegrenzt also nur noch fixen - die Datei einstellen dann läufts - alles nur Schlurifehler nichts wildes



  • kompiliert unter gcc.godbolt, und jedem anderen Linux das gerade offen ist - so ein Trivial-Programm muss kompilieren - sonst ist was mit deinen Einstellungen faul (hast du an etwas rumgespielt nachdem das 1. mal der Fehler gekommen ist?)

    also 1.

    "g++ -o programm programm.cpp"

    eingeben - Ausgabe hier posten

    "./programm dateiname"

    eingeben - Ausgabe hier posten

    solltest du den dateinamen als Parameter weglassen stürzt dein Programm ab (fehlenden Prüfung deinerseits)

    die Datei mal hier einstellen die du als Parameter angibst - oder solltest



  • Gast3 schrieb:

    kompiliert unter gcc.godbolt, und jedem anderen Linux das gerade offen ist - so ein Trivial-Programm muss kompilieren - sonst ist was mit deinen Einstellungen faul (hast du an etwas rumgespielt nachdem das 1. mal der Fehler gekommen ist?)

    also 1.

    "g++ -o programm programm.cpp"

    eingeben - Ausgabe hier posten

    "./programm dateiname"

    eingeben - Ausgabe hier posten

    solltest du den dateinamen als Parameter weglassen stürzt dein Programm ab (fehlenden Prüfung deinerseits)

    die Datei mal hier einstellen die du als Parameter angibst - oder solltest

    Ehrlich gesagt weiß ich nich was für ein Compiler die Uni benutzt. Ich habe daran sicher nichts umgestellt, ich wüsste ja gar nicht wie... Das einzige was ich getan habe ist mit "cd" Verzeichnisse wechseln. Aber natürlich NICHT während ich am Program gearbeitet habe, sondern davor.

    Die Dateien, die ich als Parameter angebe beinhalten einfach nur willkürlich gewählte Zahlenpaare, die die Dominosteine darstellen sollen.

    Die Eingabe/Ausgabe kann ich im Moment erstmal nicht mehr beisteuern, denn für heute habe ich erstmal Schluss gemacht. Ich bin schon seit 9 Uhr dran und gerade an einem Punkt, wo nichs mehr geht... Ich wage dann morgen in aller Frische einen neuen Versuch.

    Vielen Dank schonmal für eure Geduld und Zeit.



  • Ehrlich gesagt weiß ich nich was für ein Compiler die Uni benutzt

    g++ --version



  • 1. was hast du für einen gcc/g++

    g++ --version

    2. und ein Trivial-Test ob dein gcc/g++ richtig funktioniert

    --main.cpp--

    #include<stdio.h>
    
    int main() 
    {
      int* x = new int();
      delete x;
      printf("Hello World\n");
      return 0;
    }
    

    ---

    g++ -o main main.cpp

    sollte "Hello World" ausgeben



  • Ich finde es unerhört, dass auf diese Weise versucht wird, sich Punkte in der Prüfungsvorleistung zu erschleichen. Bitte versuchen Sie selbstständig die Aufgaben zu lösen. Bei Fragen können Sie sich gerne an mich wenden. 😡



  • ...

    Das Programm ist bis auf new pures C, entferne schrittweise alle Compilerwarnungen (von oben nach unten), entferne alle globalen Variablen und mache sie funktions- bzw. main-lokal evtl. übergib sie als (Zeiger)Parameter.
    Speicherzugriffsfehler haben ihre Ursache meist bei Array- bzw. allg. Speichergrenzenüberschreitungen oder uninitialisierten Variablen (würde der Compiler melden) oder falschem Zeigergebrauch.



  • Wutz schrieb:

    Das Programm ist bis auf new pures C

    Noch nicht ganz. Die Art, wie die Typen angegeben werden, ist in reinem C fehlerhaft (benötigt den Modifier union, struct , oder enum ).

    Aber das ist nur für's Archiv.



  • War nur ein kleiner Spaß. Wusste ja nicht, dass ich damit gleich solche Emotionen auslöse^^

    Sitze selber noch an der Aufgabe, bin aber recht zuversichtlich. Was die Schlussfolgerung betrifft, dass der Fehler gleich beim Herr Dr. zu suchen ist, bin ich geteilter Meinung. Es ist wirklich nicht sehr vorteilhaft in der Vorgängervorlesung die Grundlagen einer Programmiersprache in C zu lehren und dann anschließend im nächsten Semester hauptsächlich auf C++ zu wechseln.

    Kann mir gut vorstellen, dass das den ein oder anderen verwirrt. Das andere Problem ist, dass zur Vereinfachung auf viele Sachen nicht geachtet werden soll (oftmals einiges an Exceptionhandling), wobei gerade das wichtig sein wird.

    Andererseits muss man auch beachten, dass das eine Vorlesung ist, die von allen Informatik-Studiengängen besucht wird. Ist eben dann schwierig einen Mittelweg zu finden, dass alle es verstehen. Leute die vorher noch garnicht oder kaum programmiert haben, haben es da sicher am schwersten.

    Ich würde also nicht mal den Fehler beim Dr. suchen sondern, wie schon gesagt wurde, bei der Strukturierung des neuen Studiengangs. Es müsste eben eine Vorlesung für all die geben, die Informatik als Nebenfach absolvieren. Ist eben doch ungünstig alle in die selbe Vorlesung zu stecken.

    Beste Grüße und viel Erfolg



  • Gast42 schrieb:

    War nur ein kleiner Spaß. Wusste ja nicht, dass ich damit gleich solche Emotionen auslöse^^

    Der war aber leider nicht besonders lustig. Wenn du wüsstest, was du damit bei mir heute Morgen angerichtet hast...

    Allerdings, Dozenten beleidigen hilft keinem wirklich weiter. Zumal gewisse Sachen offensichtlich ein Missverständnis waren oder ich habe mich nicht deutlich ausgedrückt.

    Aber, die Aufgabe ist nunmal da, daran kann man nichts ändern und bearbeiten muss ich sie ja trotzdem.

    Wie dem auch sei. Ich habe eure Tipps beherzigt und ich denke ich bin ebenfalls auf einem guten Weg, dieses Programm noch zum laufen zu bringen.

    Ich möchte mich nochmal bedanken für die Geduld und die Tipps.


Anmelden zum Antworten