Mit Dev-C++ erzeugtes Programm stürzt ab...
-
dt2158 schrieb:
woran liegt das??
Hört sich nach undefiniertem Verhalten an. Hier funktioniert es, dort nicht. Genau deswegen eben undefiniert. Generell ist dann dein Programm "kaputt". Dh, du hast fehlerhaft programmiert. Aber ohne Kenntnis deines Codes kann man da nicht viel zu sagen.
dt2158 schrieb:
EDIT Das "Bissl" im Topic sollte "Mit" heißen, bin schon ganz verstört
Wenn das "Bissl" eigentlich "Mit" heissen sollte, dann ändere doch das "Bissl" zu "Mit".
:xmas1:
-
Ok wusste nich das man topic noch ändern kann, kann nich jedes Forum...
also hier mein tele.c letzte uni übung, wie gesagt unter linx gcc und cygwin gcc ist das kompilat ausführbar...
die tele.h is einfach der header zu..
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include "tele.h" ZeitUnion erzeuge_zufallszeit(void) { //Zufalldatumstyp GER oder US int type = rand()%2; ZeitUnion RandomTime; switch(type) { case 0: //de { ZeitTyp time; time.type = ZEIT; time.tag = rand()%30 + 1; time.monat = rand()%12 + 1; time.jahr = rand()%1000 + 1000; time.stunde = rand()%24; time.minute = rand()%60; RandomTime.de = time; } break; case 1: //us { DateTyp time; time.type = DATE; time.mmddyyyy = ((rand()%12)+1) * 1000000 + (rand()%30 + 1) * 10000 + (rand()%1000 + 1000); if(rand()%2) time.am_pm = 'A'; else time.am_pm = 'P'; time.hour = rand()%12; time.minute = rand()%60; RandomTime.us = time; } break; } return RandomTime; } void drucke_telegramm(TelegrammTyp *telegramm) { timetype type = telegramm->zeit.type; printf("\n\nTelegramm: %s",telegramm->logtext); switch(type) { case ZEIT: { printf("\nZeitstempel: DE %02d.%02d.%04d %02d:%02d\n",telegramm->zeit.de.tag,telegramm->zeit.de.monat,telegramm->zeit.de.jahr,telegramm->zeit.de.stunde,telegramm->zeit.de.minute); } break; case DATE: { printf("\nZeitstempel: US %08d (mmddyyyy) %02d:%02d\n",telegramm->zeit.us.mmddyyyy,telegramm->zeit.us.hour,telegramm->zeit.us.minute); if(telegramm->zeit.us.am_pm == 'A')printf("AM"); else printf("PM"); } break; default: printf("\nUnbekannter Zeitstempel"); } } int main() { char *text; //bewirkt, dass bei jedem Programmdurchlauf eine andere Zahlenfolge von rand() erzeugt wird; siehe http://cplus.kompf.de/artikel/random.html srand(time(0)); TelegrammTyp *telegramm; telegramm->logtext = "test"; telegramm->zeit = erzeuge_zufallszeit(); drucke_telegramm(telegramm); }
guckt ma rein
-
dt2158 schrieb:
TelegrammTyp *telegramm; telegramm->logtext = "test"; telegramm->zeit = erzeuge_zufallszeit();
Da haben wir schon den Übeltäter. telegramm ist ein Zeiger, der ins Nirvana zeigt. Jegliches Dereferenzieren ruft unweigerlich undefiniertes Verhalten hervor. Entweder du arbeitest ohne Zeiger, also
TelegrammTyp telegramm;
oder du initialisierst den Zeiger mit einem gültigen Speicherbereich.
-
geht so...
des wurde uns aber extra so offeriert zu machen, warum hab ich net mehr genau im kopf
das hatte wohl irgendwas mit der verfügbarkeit zu tun, kann dies sein? dieser Typ soll in weiteren "units" auch verwandt werden!!??
wie intialsiere ich diesen zeiger mit einem gültigen Speicherbereich?
UND: warum geht es unter linux gcc und cygwin gcc?
-
dt2158 schrieb:
wie intialsiere ich diesen zeiger mit einem gültigen Speicherbereich?
TelegrammTyp *telegramm = malloc(sizeof(struct TelegrammTyp));
UND: warum geht es unter linux gcc und cygwin gcc?
Gute Frage... vielleicht weil das Verhalten _undefiniert_ ist, wenn du einen Pointer, der irgendwohin zeigt, dereferenzierst?
Btw: Wenn logtext vom Typ char* ist, ist die Zeile
telegramm->logtext = "test";
auch unsauber...
Gruß Caipi
-
das brachte das allozieren...
80 D:\Studium\PRG2\X4\tele.c invalid application of `sizeof' to incomplete type `TelegrammTyp'
?????
-
TelegrammTyp ist wohl ein typedef. schreib einfach sizeof(TelegrammTyp) ohne "struct" davor
-
TelegrammTyp *telegramm = malloc(sizeof(struct TelegrammTyp));
ah gelöst.. konntet ihr wohl nich wissen
weil TelegrammTyp is getypdeftes structTelegrammTyp *telegramm = malloc(sizeof(TelegrammTyp));
die frage stellt sich nun warum muss ich bei *char nix allozieren?
-
daß es unter unix geht liegt vielleicht daran, daß unter vielen unixen mW ein prozess beim start immer so ziemlich den gesamten adsressraum zugewiesen bekommt. ein zugriff auf eine zufällige addresse führt dann meistens nicht zu einem absturz sondern zur zuweisung einer speicherpage an der addresse.
-
dt2158 schrieb:
die frage stellt sich nun warum muss ich bei *char nix allozieren?
Du meinst das hier?
char *text;
Nun, eigentlich musst du dafür auch einen gültigen Speicherbereich zur Verfügung stellen. Da text im weiteren Verlauf aber nicht genutzt wird, ist es erstmal egal, dass der Zeiger ins Nirvana zeigt.
Du kannst allerdings auch direkt Text zuweisen, wie zB hiertelegramm->logtext = "test";
"test" ist ein sogenanntes String Literal und dieses ist während der gesamten Laufzeit gültig. Das Problem dabei ist allerdings, und darauf wollte auch Caipi hinweisen, dass dieses Literal read-only ist. Und wenn die zugewiesene Variable vom Typ char* ist, dann ist das eine Fehlerquelle. In C++ wird das sogar als "deprecated" eingestuft, iirc. Ob das in C genauso ist, kann ich dir im Moment allerdings nicht sagen. Fakt ist, dass eine solche Variable dann besser vom Typ const char* ist. Oder du stellst halt genügend Speicher zur Verfügung, um eine Kopie des Strings zu halten, zB
char text[100] = "test"; // Platz für 100 Zeichen inklusive '\0', wird mit "test" initialisiert
Dieses Zeichenarray kannst du dann jederzeit ändern.
Und noch was, wenn du dynamisch Speicher reservierst (malloc), dann musst du den nach Benutzung auch wieder freigeben. Ansonsten bist du gleich beim nächsten Problem, Speicherlecks. Die Speicherfreigabe erledigst du mit der Funktion free. Wenn du telegramm also nicht mehr brauchst, dann fügst du folgende Zeile in dein Programm ein
free(telegramm);
Und bedenke, danach zeigt der Zeiger wieder ins Nirvana.
-
@Konfusius: Eher nicht... es gibt immerhin Segmentation Violations und die sind ganz einfach Zugriffe auf nicht existierenden Speicher.
Der OP hat ganz einfach zu viel Glueck.Wer probleme mit Pointern hat:
- Pointer immer mit NULL initialisieren, dann bleiben Fehler nicht laenger unentdeckt
- zu jedem benutzten Cast muss eine gute Begruendung her. Laesst sich keine finden, ist der Cast womoeglich ein Fehler.
-
hab einfach ma ergänzt, so sollte es dann doch safe sein wa?
telegramm->logtext = malloc(50*sizeof(char)); telegramm->logtext = "test";
-
Nein, deswegen ist "test" immer noch ein String-Literal (und außerdem hast du dort ein gewaltuges Speicherleck) - zum Kopieren von Zeichenketten verwendet C strcpy (oder memcpy).
-
dt2158 schrieb:
hab einfach ma ergänzt, so sollte es dann doch safe sein wa?
telegramm->logtext = malloc(50*sizeof(char)); telegramm->logtext = "test";
Ganz und gar nicht. Schlimmer. Du reservierst hier für
telegramm->logtext 50 Zeichen. Dann weist du telegramm->logtext ein stringliteral zu. Jetzt hast du keinen Zugriff mehr auf die angeforderten 50 chars -> Speicherleck.
so ist's richtigtelegramm->logtext = malloc(50*sizeof(char)); strcpy(telegramm->logtext ,"test");
Kurt
Edit: bin ein bissl langsam heute
-
ich muss sagen ich versteh es nich, wenn ich den string telegramm->logtext zuweise, denn is das nen unterschiedlicher adressbereich, als der den ich alozziert hab, versteh ich dat richtig???
-
Ich Denke du verstehst den Unterschied zwichen pointer und array nicht.
telegramm->logtext = "test"; // weist dem pointer auf char telegramm->logtext die adresse des stringliterals "test" zu
strcpy(telegramm->logtext ,"test"); kopiert "test" in das char array telegramm->logtext
-
ich glaube, es wird zeit fuer GRUNDLAGEN:
http://www.pronix.de/pronix-4.html