Fonction de tirage au sort aléatoire.
Salut les C,
toujours dans l'optique du projet de mon mini-serveur HTTP qui choisie une image au (pseudo) hasard dans 5 dossiers différents j'ai un petit soucis dans ma fonction de tirage au sort de l'image qui soit pour 5 itérations soit:
-me produit uneErreur de segmentation (core dumped).
-ou tire une image au sort puis me produit une Erreur de segmentation (core dumped).
dont voici le code:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
|
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
#include <time.h>
#include <fcntl.h>
int get_file_length(int fd) ;
unsigned int rand_max(int seed, int maxi) ;
struct Img_Data {
char *final_img_dir ;
char *final_img_file ;
char *tmp_img_dirname ;
} *img_data ;
void select_random_file(struct Img_Data *img_data ) ;
int main(int argc, char *argv[]) {
int c ;
for (c = 0 ; c < 5 ; c++) {
img_data=malloc(sizeof(struct Img_Data *)) ;
img_data->final_img_dir=malloc(sizeof(char *)) ;
img_data->final_img_file=malloc(sizeof(char *)) ;
img_data->tmp_img_dirname=malloc(sizeof(char *)) ;
select_random_file(img_data) ;
free(img_data->final_img_dir) ; //Peut-être inutile voir ci-dessous
free(img_data->final_img_file) ; //Peut-être inutile voir ci-dessous
free(img_data->tmp_img_dirname) ; //Peut-être inutile voir ci-dessous
free(img_data) ; // Je ne sais si cet simple appel suffit
// Essayez avec un appel a
// sleep(1) ;
}
return 0 ;
}
unsigned int rand_max(int seed, int maxi) {
srand(seed) ;
return ( ( (int) (rand()) )/ ((int) (RAND_MAX/maxi) ) ) ;
}
void select_random_file(struct Img_Data *img_data ) {
struct dirent *img_dir ;
char root_dirname[NAME_MAX]="/home/mon_nom/C" ;
char *dirname_0="/style_0/" ; // Sous-dossier de /home/mon_nom/C
char *dirname_1="/style_1/" ; // Sous-dossier de /home/mon_nom/C
char *dirname_2="/style_2/" ; // Sous-dossier de /home/mon_nom/C
char *dirname_3="/style_3/" ; // Sous-dossier de /home/mon_nom/C
char *dirname_4="/style_4/" ; // Sous-dossier de /home/mon_nom/C
DIR *root_img_dirname ;
char *dirnames[5]={dirname_0,dirname_1,dirname_2,dirname_3,dirname_4} ;
char *rand_filenames[]={} ;
time_t randseed ;
randseed=time(NULL) ;
img_data->final_img_dir=dirnames[rand_max(randseed,4)] ; // Tirage au sort d'un dossier
img_data->tmp_img_dirname=strcat(root_dirname,img_data->final_img_dir) ; // Concatenation en chemin absolus
int c=0 ;
int file_counter=0 ;
root_img_dirname=opendir(img_data->tmp_img_dirname) ; // Ouverture dossier pour itération sur les fichiers contenus
while ((img_dir=readdir(root_img_dirname)) != NULL) {
// Parcours du repertoire selectionner au hasard
if ( (char) img_dir->d_name[0] != '.' ) {
// Sauvegarde des noms de fichiers ( != '.' && != "..")
// Pour tirage au sort
rand_filenames[file_counter]=img_dir->d_name ;
//printf("DEBUG: %s\n",img_dir->d_name) ;
file_counter++ ;
}
c++ ;
}
randseed=time(NULL) ;
img_data->final_img_file=rand_filenames[rand_max(randseed,--file_counter)] ; // Tirage au sort du fichier.
closedir(root_img_dirname) ;
printf("Server relativ directory: %s\n",img_data->final_img_dir) ; // Nom de dossier tirer au sort
printf("Image file path : %s\n",img_data->final_img_file) ; // Nom de fichier tirer au sort
} |
PS: J'ai déjà produit le même algorithme avec au lieu d'une structure pour récupérer les données sur le fichier tirer au sort de simples pointeurs dans la même portée (scope) qui marchait mieux que le code montrer ci-dessus car il itérait les 5 fois mais ne supportait pas un appel a sleep(1). Et comme je pensais que le problème venait des variables pointeurs : j'ai implémenter une structure dans le but de la passer comme référence...
J'attends vos réponses éclairées avec impatience, car je suis a cours d'argument pour savoir ce qui ne va pas avec mon code.
PS: La compilation avec l'option -Wall est une bonne pratique que je vient de découvrir qui donne une sortie plus verbose du compilateur bien utile pour apprendre les bonnes manières de programmer en C.