Untypischer Laufzeitfehler durch malloc()
-
Es ist ungewöhnlich, weil hier von der Logik her "ungleich dem Wert 0" abgefragt werden soll, aber
(bool) i
ist von der Semantik her "ist i wahr?". Nun sind philosophische Wahrheit und die Integerwerte 0 und 1 in C technisch gesehen das gleiche, aber das ist eigentlich nur Willkür bei der Definition der Sprache. Daher würde ich bemängeln, wenn man diesen zufälligen Umstand ausnutzt. Reduction ad absurdum:i - true
bedeutet auch das gleiche wiei - 1
und nutzt den gleichen Sprachmechanismus aus. Wie würdest du auf so etwas im Code reagieren?
-
@hustbaer @DirkB
Ich hab den Zusammenhang nicht herstellen können. Das ist das erste mal das ich solch einen Schleifenkopf sehe, zumindest ohne einen Schreibfehler vermuten zu können. Aber für das hab ich mich ja hier angemeldet
Dank allen die mir geholfen haben.
-
@EL-europ sagte in Untypischer Laufzeitfehler durch malloc():
@john-0
Das Funktioniert so wie du schreibst. Doch in dem Übungsprogramm
steht '#if defined MSC_VER ... #elif defined linux' und ich hab kein -D__linux_ beim kompilieren gesetzt. Aber er hat den Code nach linux eingesetzt. Gibt es irgend eine Datei in welcher der Präprozässor standardmäßig Variablen wie z.B. _MSC_VER oder linux abfragt oder hat er die "in sich"? er muss ja irgendwo linux bei mir gefunden haben, sonst hätte der Aufruf der Sleep-Funktion beim compilieren einen Fehler ausgelöst.Variablen und Präprozessor Definitionen, die mit
__
anfangen sind immer vom Compiler bzw. der Laufzeitumgebung definiert. Das kann über Compiler bzw. System Header erfolgen, oder der Compiler definiert die Sachen intern, das gibt die Norm nicht vor.Mein Beispiel sollte nur zeigen, dass man leicht selbst solche Defines machen kann, und sie ebenso leicht auswerten kann. In der Realität würde man natürlich vom System definierte Präprozessor Variablen nutzen, um die Unterscheidung zwischen Windows und Linux zu machen. Nur wäre für ein Anfänger ein Ausflug in POSIX und die diversen Versionen erstmal kontraproduktiv.
-
@john-0
Danke dir für den Tip mit der Compileroption -D und #ifdef im Code. Vielleicht kannst du mir nochmal helfen? Ich hab in den Sourcen der curses lib gestöbert und versteh nur Bahnhof. Die einzelnen Funktionen in einen Zusammenhang zu bringen ist mir nicht möglich. Aber mir fiel wieder ein dort sehr häufig vorkommendes Konstrukt auf das ich nicht verstehereturn(*(int *)0);
Wird hier die 0 auf einen int-Zeiger gecastet und dann wieder der Wert 0 des Zeigers zurückgegeben? Warum gibt man hier nicht einfach 0 zurück?
-
@john-0
Ach, und danke dir auch das ich nun weiss das Variablen in den Headerdateien und im Compiler selbst vorhanden sind
-
@EL-europ sagte in Untypischer Laufzeitfehler durch malloc():
Aber mir fiel wieder ein dort sehr häufig vorkommendes Konstrukt auf das ich nicht verstehe
return(*(int *)0);Wird hier die 0 auf einen int-Zeiger gecastet und dann wieder der Wert 0 des Zeigers zurückgegeben? Warum gibt man hier nicht einfach 0 zurück?
Zunächst fällt doch auf, dass die Dateien, wo das vorkommt, mit "llib-" anfagen und keine .c oder .h-Erweiterung haben. Ich habe jedenfalls als erstes mal in die ncurses/README-Datei geschaut. Und siehe da, es gibt dort genau einen Absatz - und der bezieht sich auf diese Dateien.
Der Code dereferenziert einen Null-Pointer und gibt somit nicht 0 zurück, sondern verursacht undefiniertes Verhalten. Das ist dort Absicht. Das soll für "Linting" sein. Also vermutlich soll man die Funktionen nicht (mehr?) verwenden und wenn doch, kannst du mit
-Wnull-dereference
sehen, wo du etwas verwendest, das du nicht verwenden sollst.Jedenfalls: ich hätte mir mehr Information aus der README erhofft, wie ich diese Dateien benutzen soll - denn in meinem Programm will ich die ja sicher nicht haben - wahrscheinlich müsste ich dazu die vollständige Doku lesen.
-
@wob
Also gibt die Funktion einen uninitialisierten Speicherbereich zurück? Für mich ist das ein "harter Brocken" bewusst undefiniertes Verhalten zu erzwingen, außer man kann es irgendwo "abfangen"
Das Readme hab ich angefangen zu lesen aber dann abgebrochen weil ich die curses eigentlich cross-compilieren will und mit dem readme und meinem knappem Englisch nicht weiter kam. Danke für deine Antwort
-
@EL-europ sagte in Untypischer Laufzeitfehler durch malloc():
Also gibt die Funktion einen uninitialisierten Speicherbereich zurück? Für mich ist das ein "harter Brocken" bewusst undefiniertes Verhalten zu erzwingen, außer man kann es irgendwo "abfangen"
Sie gibt keinen "uninitialisierten Speicherbereich zurück".
Es ist ganz einfach undefiniert, was passiert. Das Programm darf crashen, der Compiler kann den Code auch ganz löschen usw. Der Compiler dürfte theoretisch auch Code einbauen, der deine Festplatte formatiert (wird er nicht tun).
Diese Libraries sind nicht zum Benutzen durch den Enduser gedacht, sondern für einen Linter.
Aber ich muss sagen, dass ich mich hiermit nicht auskenne. Vielleicht missverstehe ich das auch. Jedenfalls sind das dort ja alles nur leere Funktionen - auch die, die keinen Nullpointer dereferenzieren, haben ja einen leeren Body. Mit ist nicht klar, wozu das gut sein soll. Vielleicht kann sich ein C-Experte dazu äußern?
-
@wob sagte in Untypischer Laufzeitfehler durch malloc():
Diese Libraries sind nicht zum Benutzen durch den Enduser gedacht, sondern für einen Linter.
Der bekannteste dürfte lint sein: https://de.wikipedia.org/wiki/Lint_(Programmierwerkzeug)?wprov=sfti1
-
@wob Sorry, das fällt mir äußert schwer. Die "naive" Logig verbietet es doch Code zu Schreiben der nicht benutzt werden soll.
Kannst du mir einen Tip geben wie ich die curses auf meinem Linux, in eigenen Programmen für arm als statische lib nutzen, compilieren kann? Eine eigene trivial-lib hab ich schon einbinden können, aber curses: Da gibts Hinweise zu Konfigurieren und compilieren die ich nicht verstehe.
-
Hier zur Historie von llint-* in ncurses: https://invisible-island.net/personal/lint-tools.html
-
@EL-europ: Die "llib-"-Dateien sind nicht der Source-Code der Library, sondern dienen, wie schon geschrieben, nur zur statischen Code-Analyse (d.h. man kann damit seinen eigenen Code überprüfen lassen, ob die Aufrufe der
ncurses
-Library Funktionen korrekt sind, s. z.B. lint Libraries).Der eigentliche Source-Code der
ncurses
-Library befindet sich in den Unterordnern (d.h. die ".c"- und ".h"-Dateien).
-
@EL-europ sagte in Untypischer Laufzeitfehler durch malloc():
Die "naive" Logig verbietet es doch Code zu Schreiben der
nicht benutzt werden soll.... der nicht vom Benutzer der Library benutzt werden soll. Der aber sehr wohl von einem Tool benutzt werden soll, das Checks durchführt.
-
@DirkB ich habs eben mal ausprobiert, an der Stelle wo
(*(int *)0);
zugewiesen wird bricht das Programm mit einen Speicherzugriffsfehler ab. Was ist Lint?
-
@EL-europ sagte in Untypischer Laufzeitfehler durch malloc():
@DirkB ich habs eben mal ausprobiert, an der Stelle wo
(*(int *)0);
zugewiesen wird bricht das Programm mit einen Speicherzugriffsfehler ab.
<Loriot>Ach was!</Loriot>
Was ist Lint?
Liest du die Antworten eigentlich? (insbes. die von @DirkB)
-
@wob Eben grad. Scheint ein Tool für Checks zu sein. was wird damit gecheckt? Das scheint wohl ein breit angewendetes Tool zu sein.
Ich hab bisher meine Programme in python und php geschrieben. Da Brauch man eigentlich nur Funktionen (im web) finden und die dann kombinieren, den Rest macht der Interpreter. C ist für mich eine ganz andere Art zu Programmieren, weshalb ich es auch können will.
Sorry wenn ich hier als naiv oder gar unhöflich erscheine, ich hab immer einen Code an dem ich Teste und probiere neben dem Browser und bin als dort noch geistig gefangen.
Ich muss mir mit meinen Fragen und Beiträgen besser mehr Zeit nehmen
-
@EL-europ sagte in Untypischer Laufzeitfehler durch malloc():
Ich hab bisher meine Programme in python und php geschrieben. Da Brauch man eigentlich nur Funktionen (im web) finden und die dann kombinieren, ...
Auch da gibt es Linter. Noch nie was von
flake8
oderpylint
gehört? In PHP kenne ich mich nicht aus, aber auch da gibts sicher Linter. Jedenfalls haben die Linter ungefähr nichts damit zu tun, wie man die Libraries kombiniert.
-
@wob
auf
http://www.momefilo.hopto.org
kannst du ein php Interface für eine Datenbank von mir sehen das die Werte als Liniengrafik darstellt. Ein pythonscript liest die Daten von einem AD-Wandler über die i2c-Schnittstelle und schreibt sie in die Datenbank. Damit kann ich die Ströme meine kleine Solaranlage über die Zeit graphisch darstellen, und als Schmakerl auch übers Netzt anschauen. Und Konfigurieren, einen Schutz hab ich nicht eingebaut. Wer schaut schon auf momefilo.hopto.org nach um dort die Konfiguration zu verstellen
-
@wob
Ich hab noch nicht mit solch komplexen Programmen gearbeitet das solch ein Tool einen Vorteil brächte. Die Grundfunktionen "break" und "print" der gdb hab ich gestern zu Testzwecken probiert, mehr hab ich mich in diese Richtung noch nicht bewegt. Und mein eigentliches Ziel ist, das pythonscript welches die Daten aus der i2c-Schnittselle liest durch ein c-Programm zu ersetzen. Das ganze soll auf x86_64 für arm cross-compilert werden
-
@EL-europ sagte in Untypischer Laufzeitfehler durch malloc():
[...] weil ich die curses eigentlich cross-compilieren will [...]
Nein, das willst Du garantiert nicht, zumindest nicht für Windows. Wenn Du dieses Snake-Dings für Windows kompilieren willst, dann nimm PDCurses für Windows und ncurses für Linux und ähnliche.