Kleine Datenbank -> seltsamer Laufzeifehler
-
Hallo zusammen!
Ich bin grad mit meinen Nerven am Ende:
Ich habe vor ein paar Monaten eine kleine Hardwaredatenbank für unsere Werkstatt
angefangen. Zwischenzeitlich war ich mit so vielen Dingen beschäftigt, so das das mal liegen bleiben musste. Programmiert habe ich unter SuSE 8.0 (gcc 2.95.3) in der Zwischenzeit bin ich aber zu Debian gewechselt (gcc 2.95.4)Nun wollte ich weiter schreiben und bekomme nach dem Starten der compilierten binary einen segmentation fault geliefert. Ich habe dann die ganze Geschichte unter diversen Windows Compilern ausgetestet, das gleiche Ergebnis. Dann habe ich es nocheinmal unter SuSE getestet und was soll ich sagen, es läuft. Jetzt bin ich etwas verwirrt und weiss nicht, wo ich den Fehler suchen soll. Das Programm hat einwandfrei gelaufen und ich habe bis auf ein paar Kommentare eigentlich nichts verändert.
Hier nun der Code (ich hoffe das wird jetzt nicht zu lang )
Dei Header Datei "toolbox.h"
#define MAX 5000000 // The maximum number of database entries #define MAXFN 255 // Maximum length of filename #define TRUE 1 #define FALSE 0 #define ADD_ENTRY 1 // Definition of commands for the command parser #define VIEW_ENTRY 2 #define VIEW_ALL 3 #define OPEN_FILE 4 #define SAVE_FILE 5 #define NEW_FILE 6 #define SORT_FILE 7 #define SORT_ORDER 8 #define ENTER 13 #define FIND_ENTRY 19 #define RM_ENTRY 20 #define EDIT_ENTRY 21 #define SWAP_ENTRY 22 #define COPY_ENTRY 23 #define ADD_DETAIL 24 #define SHOW_DETAIL 25 #define LIST_DETAIL 26 #define MEM_USAGE 96 #define GET_DIR 97 #define VIEW_HELP 98 #define QUIT 99 #define INDEX 100 #define MAX_PARTS 22 // Definition of symbolic constanst for the parts of the computer #define TYPE 0 #define BOX 1 #define MAINB 2 #define CPU 3 #define COOLER 4 #define MEMORY 5 #define VGA 6 #define ETHER 7 #define SOUND 8 #define ISDN 9 #define SCSI 10 #define TVCARD 11 #define MODEM 12 #define CDROM 13 #define CDRW 14 #define DVD 15 #define HDDA 16 #define HDDB 17 #define HDDC 18 #define HDDD 19 #define KEYB 20 #define MOUSE 21 #define MONITOR 22 #define ONE 0x32 #define ALL 0x33 #define WIDTH 50 #define HEIGHT 30 // Type definitions typedef char t_bool; // Definition of a single component which consists the part description, manufacturer and serial number typedef struct components { char description[16]; char manufacturer[16]; char serial[16]; } t_component; // Definition of the computer system typedef struct computer { char number[7]; char name[16]; char processor[16]; char memory[16]; char hdd[16]; t_bool is_detail; // Are there any details available? t_bool is_tcomp[MAX_PARTS]; t_component *component[MAX_PARTS]; // Array of pointers to type t_component // for the single parts } comp; char *types[MAX_PARTS+1] = {"type","box","mainb","cpu","cooler","memory","vga","ether","sound","isdn", "scsi","tvcard","modem","cdrom","cdrw","dvd","hdda","hddb","hddc","hddd", "keyb","mouse","monitor"}; int get_data(comp *comp_pt[],int index); // Get the data for the list overview int print_data(comp *comp_pt[],int index); // Print out single data int print_all(comp *comp_pt[],int index,int from); // Print out data of all known systems int print_help(void); int get_choice(void); // What are we going to do? int get_component(void); // Which component to add int write_file(comp *comp_pt[],int index,char *filename); // Save your file to disk int open_file(comp *comp_pt[],char *filename); // Open your file from disk int copyright(void); // Show the copyright void q_sort(comp *comp_pt[],int left,int right); // Simple quick sort routine void swap(comp *comp_pt[],int i,int j); // Swap two elements from the list void sort_order(comp *comp_pt[],int index); // Inverse the sort order int rm_entry(int entry,comp *comp_pt[],int index); // Remove entry from the list int is_entry(int index); // Is the chosen entry valid? int is_index(int index); // Is there any entry? int find_entry(comp *comp_pt[],char *string,int index); int edit_entry(comp *comp_pt[],int entry); // Edit any list entry int copy_entry(comp *comp_pt[],int entry,int index); // Copy entry to the end of the list int add_comp(comp *comp_pt[],int entry,int t_number); // Add a component to a system int show_detail(comp *comp_pt[],int entry,int t_number,int mode); // Show the details of a system int add_detail(comp *comp_pt[],int entry,char choice); // Add the details
Und toolbox.c :
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <stddef.h> #include <sys/types.h> #include <malloc.h> #include "toolbox.h" int main() // The main program { int my_entry; // Which my_entry in the list do we mean int index; // How many entries do we have int choice; // What are we going to do? int dummy; // Our little wastebasket int i,j; int last; int last_matches; // needed for swapping entries char my_string[16]; comp *comp_ptr[MAX]; // array of pointers to type comp char filename[MAXFN]; index = 0; // At the beginning obviously none copyright(); // Copyright message do { choice = get_choice(); // get the users choice switch(choice) { case VIEW_HELP : print_help(); break; case ADD_ENTRY : get_data(comp_ptr,index++); // Get data, set number of entries (index) + 1 comp_ptr[index-1]->is_detail = FALSE; // At this moment, no details are available break; case EDIT_ENTRY : if (my_entry = is_entry(index)) edit_entry(comp_ptr,my_entry-1); break; case COPY_ENTRY : if (my_entry = is_entry(index)) copy_entry(comp_ptr,my_entry-1,index++); break; case ADD_DETAIL : if (my_entry = is_entry(index)) add_detail(comp_ptr,my_entry-1, get_component()); break; case SHOW_DETAIL: if (my_entry = is_entry(index)) show_detail(comp_ptr,my_entry-1,get_component(),ONE); break; case LIST_DETAIL: if (my_entry = is_entry(index)) show_detail(comp_ptr,my_entry-1,MAX_PARTS,ALL); break; case VIEW_ENTRY : if (my_entry = is_entry(index)) print_data(comp_ptr,my_entry-1); break; case FIND_ENTRY : scanf("%s",my_string); last_matches = find_entry(comp_ptr,my_string,index-1); printf("\n%d entries found",last_matches); break; case VIEW_ALL : if (is_index(index)) if (my_entry = is_entry(index)) print_all(comp_ptr,index,my_entry-1); break; case SAVE_FILE : if (is_index(index)) { scanf("%s",filename); write_file(comp_ptr,index,filename); } break; case OPEN_FILE : scanf("%s",filename); index = open_file(comp_ptr,filename); break; case NEW_FILE : for (my_entry = 0;my_entry < index;my_entry++) { // When a new file is created, we have for (last = 0;last < MAX_PARTS;last++) if (comp_ptr[my_entry]->is_tcomp[last] = TRUE) free(comp_ptr[my_entry]->component[last]); free(comp_ptr[my_entry]); // to free the memory for ALL the pointers } index = 0; break; case SORT_FILE : if (is_index(index)){ // Alphabetically sorting q_sort(comp_ptr,0,index-1); } break; case SORT_ORDER : if (is_index(index)){ // Inverse sort order of pointers sort_order(comp_ptr,index-1); } break; case RM_ENTRY : if (my_entry = is_entry(index)) // remove my_entry index = rm_entry(my_entry-1,comp_ptr,index); break; case SWAP_ENTRY : if (i = is_entry(index)) if (j = is_entry(index)) swap(comp_ptr,i-1,j-1); // swap my_entry break; case INDEX : printf("\nDatabase : %s",filename); printf("\n%d entries\n",index); ; break; case ENTER : break; default : break; } if (choice != ENTER) scanf("%c",&dummy); // remove any waiting character } while (choice != QUIT); for (my_entry = 0;my_entry < index;my_entry++) { // clean up memory for (last = 0;last < MAX_PARTS;last++) if ((comp_ptr[my_entry]->is_detail) == TRUE) if ((comp_ptr[my_entry]->is_tcomp[last]) == TRUE) free(comp_ptr[my_entry]->component[last]); free(comp_ptr[my_entry]); // to free the memory for ALL the pointers } return 0; } }
(Aus Gründen der Übersichtlichkeit gekürzt)
Könnte sich das mal ein Spezi (Shade? :D) ansehen?
GreetZ
ReSeT[ Dieser Beitrag wurde am 22.10.2002 um 17:29 Uhr von ReSeT editiert. ]
-
Deine Variable comp_ptr in der main-Funktion belegt zuviel Speicher auf dem Stack. Entweder erhöhst du die Größe des Stacks oder du legst den Speicher dynamisch mit malloc an. ( ! free am Ende von main nicht vergessen !)
[Edit]Vielleicht solltest du generell mal die Größe von MAX ändern, so viel Speicher brauch doch keine Sau.[/Edit]
[ Dieser Beitrag wurde am 22.10.2002 um 15:47 Uhr von thomas80d editiert. ]
-
BTW.
benutzt doch bitte den GDB, der hat eine sehr schöne Funktion bt, mit der du bei einem Segfault sehen kannst, wo er auftritt und dann leicht siehst warum.
-
@thomas80d : Vielen dank, das wars, ich hatte diesen Wert irgendwann mal zu Testzwecken hochgesetzt und Ihn irgendwie völlig übersehen (oh mann)
Many THX
-
Da wäre nur noch die Frage offen, warum der gcc 2.95.3 unter SuSE das
anstandslos frisst und sich die ausführbare Datei auch problemlos ausführen lässt.