Programme qui fait planté mon PC, je dois remplir une pile t

Discutez d'informatique ici !
Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 19:42

Programme qui fait planté mon PC, je dois remplir une pile t

par Rockleader » 14 Oct 2014, 11:33

Hello j'ai réussi à faire crasher mon pc avec ce programme, j'aimerais bien savoir ce qui ne vas pas dedans parce que là je vois pas du tout !!!

Le but est d'afficher le contenu de plusieurs fichiers passé en paramètre à l'écran Ou dans fichier si on fait une redirection
En c of course^^

Erreur.c

Code: Tout sélectionner
void Erreur(char *Message, int retour)
{
   perror(Message);
   exit(retour);
}



afficher.c

Code: Tout sélectionner

#define TAILLE 512

int afficher(char *nomFichier)
{
   char buffer[TAILLE];
   int nbLu=0;
   int fd=open(nomFichier,O_RDONLY,0);
   if(fd!=-1)
   {
      while((nbLu=read(fd,buffer,TAILLE))!=0) //tant que l'on a pas lu tout le fichier
      {
         write(1,buffer,nbLu);
      }
   }
   else
   {
      Erreur("open:",99);
   }
   return 0;
}


Le main

Code: Tout sélectionner
int main(int argc, char const *argv[])
{

   int k;
   int estPresent=0;
   int estEgal=-1;
   int pos=-1;
   //argv[0] est le nom du programme on ne le traite pas
   for(k=1;k concat dans fich
      strcat(fich,argv[k]);
      estEgal=strcmp(">",argv[k]);//On cherche s'il y a une redirection
      if(estEgal==0)
      {
         estPresent++;
         pos=k+1;//on stocke la position du dernier fichier où on va écrire
      }   
   }
   if(estPresent==0)//s'il n'y a pas de redirection, on affiche tous les fichiers sur l'écran
   {
      for(k=1;k concat dans fich
         strcat(fich,argv[k]);
         afficher(fich);
      }
   }
   else//s'il y a une redirection
   {
      char* fichDest="";
      fichDest = malloc (50 * sizeof(char));
      strcat(fichDest,argv[pos]);
      int fd=open(fichDest,O_WRONLY,0);
      if(fd!=-1)
      {
         //si le fichier est bien ouvert en écriture
         int save=dup(1);//sauvegarde de l'écran
         dup2(fd,1);//on écrase l'écran avec fd
         close(fd);//on garde uniquement la copie dans

         /***On réalise l'affichage***/
         for(k=1;k comme un fichier !!!
            {
               char* fich="";
               fich = malloc (50 * sizeof(char));
               //argv étant un const char* on ne peut pas l'utiliser directement dans afficher ==> concat dans fich
               strcat(fich,argv[k]);
               afficher(fich);
            }
         }
         dup2(save,1);//on replace la sauvegarde de l'écran dans 1
         close(save);//supression du doublon

      }
      else //si le fichier ou on veut écrire n'existe pas
      {
         Erreur("open: Le fichier Destination n'existe pas",99);
      }

   }
   return 0;
}


Il semblerait que j'écrive les fichiers passé en paramètres à l'infini dans le fichierDestination et franchement je vois pas du tout pourquoi ça me fait ça è_é
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !



Cliffe
Membre Rationnel
Messages: 967
Enregistré le: 12 Juin 2012, 14:25

par Cliffe » 14 Oct 2014, 12:10

J'ai pas lu ton code mais ça ma l'air super compliquer pour simplement afficher le contenu de fichiers ...

Escargot92
Membre Naturel
Messages: 11
Enregistré le: 12 Mai 2014, 12:25

par Escargot92 » 14 Oct 2014, 12:25

Trop de commentaire empêche la bonne lisibilité du code. Quand tu dis que ca fait crasher ton pc, cela signifie que ton pc s'arrête ou que seul le programme crash?
Pour trouver l'endroit ou sa crash soit tu met des breakpoint et tu lance le programme pas à pas.
Sinon utilise des printf (ex: "printf("dbg 1\n");") aprés chaque copie/concat de données: strcat,...

Pourquoi t'as mis 1 en argument de write()?
Tu l'as défini ou elle provient d'une bibliothéque.Dans ce dernier cas:
int write( int handle, void *buffer, int nbyte );

Le int correspond au fichier où tu vas ecrire ou une var system.
int fileOut = open(...);
write( fileOut , buffer, nbyte);

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 19:42

par Rockleader » 14 Oct 2014, 16:08

Il n'y a pas d'erreur de compilation seulement à l'exécution.

C'est peut être compliqué mais c'est les consignes =)
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

Cliffe
Membre Rationnel
Messages: 967
Enregistré le: 12 Juin 2012, 14:25

par Cliffe » 14 Oct 2014, 16:47

Il faut bannir les malloc et les new le plus possible.
Je vois pas comment un prog en C peut faire planter le PC. Tes bien sous windows ?

Voila un exemple de code pour afficher des fichiers dans la console :

Code: Tout sélectionner
std::vector list_files;
// Ajouter des fichiers qui existent

for (std::vector::iterator file = list_files.begin(); file != list_files.end(); ++ file) {
    std::string ligne;
    while (getline(**file, ligne)) {
        std::cout << ligne << std::endl;
    }
}

Avatar de l’utilisateur
ampholyte
Membre Transcendant
Messages: 3940
Enregistré le: 21 Juil 2012, 08:03

par ampholyte » 14 Oct 2014, 17:54

Bonjour,

Escargot92 a écrit:Pourquoi t'as mis 1 en argument de write()?


Je ne sais pas si tu as vu l'erreur relevée par Escargot92 mais dans ton fichier affiche.c il faudrait avoir :
Code: Tout sélectionner
write(fd, buffer, nbLu);


Ensuite comme l'explique escargot92, essaye de rajouter des traces aux étapes les plus importantes pour savoir à quel moment précisemment, ton programme plante (tu peux rajouter des sleep de 2 / 3 secondes histoire de voir passer les logs ^^, si le pc plante et que tu ne peux pas voir les erreurs qui ont pu être affichées).

Avatar de l’utilisateur
fatal_error
Modérateur
Messages: 6610
Enregistré le: 22 Nov 2007, 13:00

par fatal_error » 14 Oct 2014, 20:30

hello,

un peu plus sexy que des getline à mon gout:
Code: Tout sélectionner
#include
#include
#include
#include
int main(){
  std::fstream f("toto.txt");
  std::copy(
    std::istreambuf_iterator(f),
    std::istreambuf_iterator(),
    std::ostream_iterator(std::cout)
  );
  return 0;
}

mais bon, de toute façon, il me semble que rockleader fait du C.

Plusieurs questions:
ca me surprend qu'il faille et que tu puisses utiliser l'opérateur de redirection de flux.
parce qu'il me semble que c'est géré au niveau du shell
à part passer les arguments du style
./exe "blabla > fichier"
à la place d e
./exe "blabla" > fichier,
je vois pas comment tu y auras accès et quand bien même ca me parait stupide...

Aussi, il serait temps que tu factorises ton code par des appels de fonctions

et accessoirement, un malloc==un free!!!!!
la vie est une fête :)

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 19:42

par Rockleader » 14 Oct 2014, 21:07

Justement ampholyte je suis d'accord avec ce que tu dis.


Mais on m'a fait écrire la fonction au début en spécifiant bien la valeur 1 (et non fd; même si fd vaut 1 au final pour l'écran...)



Là dans ce main il faut refaire le travail; sans modifier la fonction afficher, ce qui est un tantinet plus drôle :ptdr:


et accessoirement, un malloc==un free!!!!!


Sa c'est vrai :marteau:


Tes bien sous windows ?


nop, je fais mes cours de programmation multitâches sur linux ;)

Aussi, il serait temps que tu factorises ton code par des appels de fonctions


La dernière fois que j'ai fais ça, le super programme de vérification de code des profs m'a compté mon exo faux parce que j'avais fais une fonction non demandé...

Donc maintenant quand c'est noté, je fais ce qu'on me demande, ni plus ni moins :hein:

Mais je reste d'accord avec toi...

ca me surprend qu'il faille et que tu puisses utiliser l'opérateur de redirection de flux.
parce qu'il me semble que c'est géré au niveau du shell
à part passer les arguments du style


Oui le shell fait bien cela, mais là le but c'est de le faire en C...il n'y a pas spécialement de logique à chercher, faut juste le faire c'est des cas d'écoles on a jamais dit que c'était intelligent :ptdr:



plus sérieusement le vrai but de l'exo consiste dans le fait de changer l'affichage, si je ne met pas l'opérateur de redirection je dois afficher sur l'écran le contenu des fichiers.
Easy ;) Suffit de boucler sur chaque fichier passé en paramètre si > n'est pas dans la liste des paramètres.


Si > est présent.

==> Il faut afficher dans le fichier suivant >

Donc dans le fichier de fd Destination sans changer la fonction afficher, impossible donc de mettre fd !!!


Il faut donc jouer avec les dup pour switcher ce que représente le fd==1.
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

joel76
Membre Relatif
Messages: 230
Enregistré le: 11 Fév 2013, 16:31

par joel76 » 14 Oct 2014, 21:11

Dans la fonction afficher, tu ne fermes jamais le fichier que tu as ouvert.

joel76
Membre Relatif
Messages: 230
Enregistré le: 11 Fév 2013, 16:31

par joel76 » 14 Oct 2014, 21:28

Le problème, quand il y a redirection, est que tu vas jusqu'à argc dans ta boucle d'écriture, donc tu écris le fichier de destination dans le fichier de destination ...
Arrête-toi à pos-1 et ça devrait tourner.

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 19:42

par Rockleader » 14 Oct 2014, 21:34

joel76 a écrit:Le problème, quand il y a redirection, est que tu vas jusqu'à argc dans ta boucle d'écriture, donc tu écris le fichier de destination dans le fichier de destination ...
Arrête-toi à pos-1 et ça devrait tourner.



En voilà une bonne idée :zen:

Effectivement j'écris le fichier destination dans le fichier destination.
Par contre ça n'explique pas vraiment que ça l'écrive à l'infini. A moins qu'ils ne détecte qu'il est modifié à chaque fois, et dans ce cas là, le CPU doit vraiment morfler ><


En tout cas je vais faire ça, je sais pas si ça réglera tout le problème mais ça en règlera au moins la moitié^^


Dans la fonction afficher, tu ne fermes jamais le fichier que tu as ouvert.


C'est vrai que je n'y avais pas pensé. Je vais le faire aussi :lol3:
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

Avatar de l’utilisateur
fatal_error
Modérateur
Messages: 6610
Enregistré le: 22 Nov 2007, 13:00

par fatal_error » 14 Oct 2014, 21:49

en tout cas, un programme intéressant, ca serait un programme qui prend ton fichier, qui récupère les fonctions flaggées comme à remplacer (idem inline) et qui remplace leurs appels par le code équivalent!

c'est pas trivial, mais avec certaines restrictions, ca te permettrait de pouvoir développer serainement et de processer pour le rendu final...
la vie est une fête :)

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 19:42

par Rockleader » 14 Oct 2014, 22:34

les fonctions flaggées comme à remplacer (idem inline)


J'ai pas compris ce que tu as voulu dire là.
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

Avatar de l’utilisateur
fatal_error
Modérateur
Messages: 6610
Enregistré le: 22 Nov 2007, 13:00

par fatal_error » 14 Oct 2014, 22:39

Code: Tout sélectionner
/**
 @inline
*/
int doSomething(){printf("toto");}
int another(){}

int main(){
 doSomething();
 another();
}


=>devient
Code: Tout sélectionner
int another(){}

int main(){
 printf("toto");
 another();
}
la vie est une fête :)

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 19:42

par Rockleader » 14 Oct 2014, 22:41

C'est vrai que ça pourrait être pas mal ça, pratique et réutilisable^^
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

 

Retourner vers ϟ Informatique

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 3 invités

Tu pars déja ?



Fais toi aider gratuitement sur Maths-forum !

Créé un compte en 1 minute et pose ta question dans le forum ;-)
Inscription gratuite

Identification

Pas encore inscrit ?

Ou identifiez-vous :

Inscription gratuite