J'ai un code ANSI C que j'ai développé sur mon Mac, mais quand j'ai essayé de l'exécuter sur les serveurs Linux de notre école, j'ai un erreur de segmentation.ANSI C getc provoque une erreur de segmentation sur Linux mais pas sur OS X
La ligne spécifique qui me cause un problème est getc
à partir d'un pointeur de fichier.
Le fichier existe.
est la méthode ici en question:
// inits lists with all data in fp file pointer
// returns # of lines read
int init_intlists(FILE *fp, INTLIST *lists[]) {
int c, ctr;
ctr = 0;
// need to use a linked list to store current number
// for non 1-digit numbers...
INTLIST *cur_num = NULL;
int cur_num_len = 0;
while ((c = getc(fp)) != EOF){
if(c != '\n' && c != ' '){
c = c - 48;
if(cur_num == NULL){
cur_num = init_intlist(c);
} else {
list_append(cur_num, &c);
}
cur_num_len++;
} else if(c == ' ' || c == '\n'){
// we reached a space, meaning we finished
// reading a contiguous block of digits
// now we need to figure out what we actually read...
int num = 0;
INTLIST *ptr;
ptr = cur_num;
while(cur_num_len != 0){
cur_num_len--;
num += pow(10, cur_num_len) * ptr->datum;
ptr = ptr->next;
}
if(lists[ctr] == NULL){
// init new list
lists[ctr] = init_intlist(num);
} else {
// append to existing
list_append(lists[ctr], &num);
}
// clear cur_num to read the next one
cur_num_len = 0;
list_delete(cur_num);
cur_num = NULL;
}
if(c == '\n') {
// newline reached - increment to fill in next list
ctr++;
}
}
return ctr;
}
L'appel à init_intlists
qui provoque l'erreur de segmentation commence ainsi:
FILE *fp = (FILE *)malloc(sizeof(FILE));
FILE *base_vector_fp = (FILE *)malloc(sizeof(FILE));
parse_args(argc, argv, fp, base_vector_fp);
if(fp == NULL || base_vector_fp == NULL){
fprintf(stderr, "Critical error, could not load input files\n");
return 1;
}
INTLIST *lines[MAX_LINES] = {};
INTLIST *base_vectors[MAX_LINES] = {};
int lines_read = init_intlists(fp, lines);
et parse_args
ressemble:
FILE *load_file(char *filename) {
FILE *fp;
fp = fopen(filename, "r");
if(fp == NULL){
fprintf(stderr, "File %s does not seem to exist.\n", filename);
return NULL;
}
// XXX Does this memory leak?
// fp is never fclose()'d
return fp;
}
void parse_args(int argc, char *argv[], FILE *fp, FILE *base_vector_fp) {
char *prog = argv[0];
if (argc != 3){
fprintf(stderr, "Wrong number of arguments supplied.\nUse: %s <data_filename> <base_vector_filename>\n", prog);
free(fp);
free(base_vector_fp);
fp = NULL;
base_vector_fp = NULL;
exit(1);
}
char *filename = argv[1];
*fp = *load_file(filename);
char *base_vector_filename = argv[2];
*base_vector_fp = *load_file(base_vector_filename);
}
Ainsi, lorsque J'essaie d'invoquer ceci sur mon Mac, ça marche parfaitement bien et ça lit e file comme il se doit et je suis capable de travailler dessus et d'obtenir les bonnes réponses pour mon devoir.
Cependant, lorsque j'essaie de l'exécuter sous Linux, j'obtiens une erreur de segmentation quand elle essaie de getc
dans le sous-programme init_intlists
.
J'ai vérifié que les fichiers que je fournis pour l'entrée existent et sont lisibles dans le monde entier (umask 755). J'ai essayé avec des chemins absolus et relatifs. J'ai aussi essayé plusieurs fichiers d'entrée différents.
J'ai essayé d'utiliser gcc 4.2
et gcc 3.4
sur le serveur Linux et tous deux produisent un exécutable binaire qui provoquera un segfault avec des fichiers d'entrée donnés.
Voici les informations de version entre les deux versions différentes de gcc:
Mac OS X:
[email protected] ~> gcc -v
Using built-in specs.
Target: i686-apple-darwin9
Configured with: /var/tmp/gcc/gcc-5465~16/src/configure --disable-checking -enable-werror --prefix=/usr --mandir=/share/man --enable-languages=c,objc,c++,obj-c++ --program-transform-name=/^[cg][^.-]*$/s/$/-4.0/ --with-gxx-include-dir=/include/c++/4.0.0 --with-slibdir=/usr/lib --build=i686-apple-darwin9 --with-arch=apple --with-tune=generic --host=i686-apple-darwin9 --target=i686-apple-darwin9
Thread model: posix
gcc version 4.0.1 (Apple Inc. build 5465)
Linux:
[email protected]:~/assignment_1$ gcc -v
Using built-in specs.
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --enable-languages=c,c++,fortran,objc,obj-c++,treelang --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --with-gxx-include-dir=/usr/include/c++/4.2 --program-suffix=-4.2 --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-mpfr --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.2.4 (Ubuntu 4.2.4-1ubuntu4)
J'invoque le compilateur en utilisant le même Makefile
sur OS X et Linux. L'invocation de fin de gcc
vents ressemble à ceci:
gcc -Wall -g -c src/common_file_io.c src/main.c src/intlist.c
gcc -Wall -g common_file_io.o main.o intlist.o -lreadline -lm -o bin/myprogram
Toutes les idées? Je suis complètement perdu, tout comme mon professeur.
Conseil amical: Essayez de réduire le texte global, c'est un peu trop à parcourir et vous obtiendrez peut-être moins de réponses. – csl
Pourquoi êtes-vous 'malloc'ing mémoire pour' FILE * 's? – pmg