C-Programm läuft unter Windows aber nicht unter Linux
-
Hallo,
habe ein großes
Problem
.
Ich habe ein Programm geschrieben (oder versucht zu schreiben), welches mir einen "riesigen" String in mehrere Teilstrings zerhäckselt. Diese Teilstrings sind jeweils hexadezimale Werte, welche ich anschließend in einen dezimalen Wert umwandle und durch Kommas getrennt in eine Datei schreiben lasse.
Unter Windows funktioniert das Ganze mit dem Dev-C++ Compiler hundertprozentig.
Unter Linux wollte ich das Ganze nachahmen mit dem GCC, welcher mir die Source auch ohne Fehler kompiliert, nur bei der Ausführung bricht das Programm jedesmal mit einem Speicherzugriffsfehler ab.#include <stdio.h> #include <string.h> void umdrehen(char *help, FILE *daten, int a) { int i,j,k,l,m; char var1,var2; char *test; test=(char*)calloc(help); long konv2; j=-2; printf("\n"); m=strlen(help); for(i=m;i>=2;i-=2) { j=j+2; k=i-1; l=i-2; var1=help[k]; var2=help[l]; test[j]=var2; test[j+1]=var1; } sscanf(test, "%lx", &konv2); if ((a>0) && (a<22)) fprintf(daten,"%ld,",konv2); if (a==22) fprintf(daten,"%ld;\n",konv2); free(konv2); free(test); } int main(void) { char buf[200] = "AAAA684343681400000040000B0F090001000AEABF3E010000009900990052020C00E80084138A006B014814B80BE80085137701D40D8F01DA037E1A67064F1DDC01210B0000FD060000E70FE4130700471116F8"; int len[30] = {36,8,8,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,8,8,8,8,8,2,2,4,2,2}; int vr[30] = {0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,1,1,1,0,0,1,0,0}; int i,j,k,l,a; char opr; char help[200]; FILE *daten; long konv; putchar('\n');putchar('\n'); j=0; k=0; l=0; daten = fopen("daten.txt","a"); for(i=0;i<29;i++) //Schleife läuft durch "len" durch und ermittelt die benötigten ASCII-Byte Längen { for(j=l;j<(len[i]+l);j++) //Schleife um die Werte aus buf von der Anfangsstelle l an auszulesen und in help zu speichern { opr=buf[j]; help[k]=opr; k=k+1; } l=l+len[i]; // Bestimmt die Stelle an der aus der Variablen buf angefangen wird auszulesen help[k]='\0'; putchar('\n'); a=i; if (vr[i]==1) { umdrehen(help, daten, a); } else { putchar('\n'); sscanf(help, "%lx", &konv); if ((i>0) && (i<22)) fprintf(daten,"%ld,",konv); if (i==22) fprintf(daten,"%ld;\n",konv); } free(konv); k=0; } fclose(daten); putchar('\n'); }
Ich weiß echt nicht mehr weiter.
Wäre echt super, wenn mir jemand helfen könnte.
Ich bin auch ein absoluter Newbie in Sachen C unter Linux und deshalb auf jede Hilfe angewiesen.MfG
MTC
-
wundert mich, dass er das compiliert. eine calloc-Funktion, die ein char* als Argument haben will, hab ich jedenfalls noch nicht gesehen.
-
Ob du es glaubst oder nicht, der kompiliert das !!!
Und dieses komische (char*) hab ich reingemacht, da der mir immer folgende Fehlermeldung ausgegeben hat:
[Warning] assignment makes pointer from integer without a cast
Und da hab ich einfach das (char*) davor geschrieben, als cast und dann ging das ohne Fehler !!
-
Ich rede vom Argument. calloc erwartet normalerweise zwei size_t Argumente. Du aber rufst calloc(help) auf, wobei help ein char* ist.
Ich seh aber grade woher der Fehler kommt. Du hast vergessen stdlib.h einzubinden. Dadurch ist calloc dem Compiler unbekannt, so dass er eine Funktion mit beliebigen Argumenten und Rückgabetyp int annimmt. Das heißt, er bemerkt nicht, dass du die Funktion falsch aufrufst. In so einem Fall ist das Verhalten undefiniert. Dass es unter Windows funktioniert wundert mich ehrlich gesagt, das ist Zufall.
-
Du solltest stdlib.h einbinden, dann beschwert sich der Compiler auch über den falschen Funktionsaufruf. Ausserdem empfiehlt es sich beim gcc mit -W -Wall zu kompilieren.
Tatsächlich mal Fall wo es schlecht ist den Rückgabewert von malloc() zu casten, hab immer gedacht das kommt ja doch eh nie vor
-
Das ich die Fehler angezeigt bekomme, wenn ich die "stdlib.h" einbinde, sehe ich ja ein, nur wie löse ich das Problem ???
Vielen Dank schonmal im Voraus !
MTC
-
Indem du calloc richtig einsetzt. Ich weiß nicht wirklich was du da tun willst, aber ich vermute, es könnte helfen, wenn du die Zeile streichst und weiter unten folgendes einfügst:
. printf("\n"); m=strlen(help); // hier einfügen: test = malloc(m); for(i=m;i>=2;i-=2) {
Ich hab jetzt malloc genommen, aber wenn es unbedingt calloc sein muss, dann test = calloc(m, 1);
-
Zu dem CALLOC muss ich sagen, dass ich das irgendwo gelesen habe, hatte vorher auch MALLOC stehen, weiss aber nicht mehr, wieso ich das geändert habe.
Hier ist nun die geänderte Source:
#include <stdio.h> #include <string.h> #include <stdlib.h> void umdrehen(char *help, FILE *daten, int a) // Funktionsaufruf mit einem Pointer auf das Array der help-Variablen { int i,j,k,l,m; char var1,var2; char *test; j=-2; printf("\n"); m=strlen(help); test = malloc(m); for(i=m;i>=2;i-=2) // Schleife um die HEX-Bytes von hinten nach vorne umzudrehen, sofern benötigt { j=j+2; k=i-1; l=i-2; var1=help[k]; var2=help[l]; test[j]=var2; test[j+1]=var1; } sscanf(test, "%lx", &konv2); if ((a>0) && (a<22)) fprintf(daten,"%ld,",konv2); if (a==22) fprintf(daten,"%ld;\n",konv2); printf("\n"); free(test); // Hier wird der von test belegte Speicher wieder freigegeben !!! } int main(void) { char buf[200] = "AAAA684343681400000040000B0F090001000AEABF3E010000009900990052020C00E80084138A006B014814B80BE80085137701D40D8F01DA037E1A67064F1DDC01210B0000FD060000E70FE4130700471116F8"; int len[30] = {36,8,8,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,8,8,8,8,8,2,2,4,2,2}; int vr[30] = {0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,1,1,1,0,0,1,0,0}; int i,j,k,l,a; char opr; char help[200]; FILE *daten; long konv; putchar('\n');putchar('\n'); j=0; k=0; l=0; daten = fopen("daten.txt","a"); for(i=0;i<29;i++) //Schleife läuft durch "len" durch und ermittelt die benötigten ASCII-Byte Längen { for(j=l;j<(len[i]+l);j++) //Schleife um die Werte aus buf von der Anfangsstelle l an auszulesen und in help zu speichern { opr=buf[j]; help[k]=opr; k=k+1; } l=l+len[i]; // Bestimmt die Stelle an der aus der Variablen buf angefangen wird auszulesen help[k]='\0'; putchar('\n'); a=i; if (vr[i]==1) { umdrehen(help, daten, a); } else { putchar('\n'); sscanf(help, "%lx", &konv); // Umwandlung help (HEX-String) in konv (Integer-Wert) if ((i>0) && (i<22)) fprintf(daten,"%ld,",konv); if (i==22) fprintf(daten,"%ld;\n",konv); } k=0; } fclose(daten); putchar('\n'); }
so leid es mir tut, das Proggi verursacht immer noch einen Speicherzugriffsfehler unter Linux, wobei es aber unter Windows geht.
Bin echt für jede Hilfe dankbar.
P.S.: Der Sinn dieses Programmes ist:
Den String, der in BUF steht, bekomme ich von der seriellen Schnittstelle und in diesem stehen viele viele einzelne Werte drin. Diese Werte wollt ich aus dem Gesamtstring rausholen und in dezimaler Form in eine Datei schreiben, eventuell auch in eine Datenbank, da ich später diese Werte mit PHP darstellen will, in Form von Diagrammen und Statistiken.
Alle diese Einzelstrings sind Werte in headezimaler Form. Bei manchen muss ich eine byteweise Umsortierung von hinten nach vorne vornehmen; deshalb auch die Funktion UMDREHEN.
-
Ich muss mich korrigieren:
Das Programm funktioniert schonmal ohne Speicherzugriffsfehler !!!
Nur habe ich jetzt folgendes Problem:
Die Hexadezimal Werte, welche in der Funktion UMDREHEN gedreht, also byteweise umsortiert werden, werdenn anschließend nicht mehr richtig in Dezimalwerte umgewandelt.
Woran kann das liegen ???
-
Kann es sein, dass durch die geänderte Anweisung
test=malloc(m);
dazu kommt, dass "test" nicht vom selben Datentyp und von derselben Größe wie "help" ist ???
Ich würde ja gerne auch nur das "help" benutzen, weiss aber nicht, wie ich mit dem help in der Funktion arbeite, da es ja aus dem Hauptprogramm übergeben wird.
Vielen Dank schonmal.
MfG
MTC
-
malloc(m+1) wär glaub ich sinnvoller. Der Sinn der Übung liegt darin, jedenfalls solange ich deine Gedanken richtig lese, dass für test soviel Speicher reserviert wird wie help belegt. Das heißt strlen(help) + 1. strlen(help) steht in m, also m+1.
-
Genau das hab ich mir auch gedacht und auch gemacht.
Du bist halt schneller im Schreiben als ich im Denken und Ausführen.
Unter Windows läuft das ganze jetzt wunderbar, nur unter Linux noch nicht.
Wie muss ich das ganze Ding denn jetzt kompilieren unter Linux ???Ich mach das nämlich immer so:
gcc main.c -o main
Kann ich das so machen oder muss ich noch irgendwelche LIBS mit einbinden bzw. irgendwelche Parameter setzen ???
-
wie gesagt, Warnungen einschalten:
gcc -W -Wall main.c -o main
-
Der Aufruf ist an sich richtig so. Man könnte noch die Optionen -W -Wall -ansi hinzufügen, um mehr Warnungen bei fragwürdigen Konstrukten zu bekommen.
-
So ich hab jetzt nun den Aufruf wie DrGreenthumb
gemacht und folgende Fehlermeldung erhalten:Zeile 82: [Warning] control reaches end of non-void function
Nur leider weiss ich noch immer nicht, warum die Umwandlung von hex nach dez in der UMDREHEN Funktion nicht klappt.
Ich weiss zwar, dass ich nervig bin, aber ich werd sonst noch wahnsinnig.
Vielen Dank schon mal !