Langage C

Discutez d'informatique ici !
Avatar de l’utilisateur
fatal_error
Membre Légendaire
Messages: 6610
Enregistré le: 22 Nov 2007, 12:00

par fatal_error » 09 Déc 2013, 20:02

http://fr.wikipedia.org/wiki/M%C3%A9moire_vive
la mémoire vive, c'est la ram..

si t'as plus de mémoire vive, le système swap. C'est à dire qu'il store les données temporairement sur le disque dur (temps d'accès divisé par 100 je crois, vérifies).

Concernant les 2Go d'utilisation, généralement l'OS alloue une certaine quantité MAX de mémoire vive pour chaque processus. Pour mon linux c'est 2go, après ca segfault. Ca se modifie, bien sûr...
la vie est une fête :)



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

par Rockleader » 09 Déc 2013, 22:44

Re/bonsoir

J'ai continué à chercher; mais je ne vois pas ce qui me provoque l'erreur de segmentation; peut être que je me trompe en ce qui est de l'utilisation des fonctions fgets et fputs.

Le but du sous programme est de recopier les mots d'un fichier dans un second fichier qui sera créer.

Code: Tout sélectionner
void copieMot(char* adresse)
{
   FILE *registre =NULL;
   FILE *registre2 =NULL;
   registre=fopen(adresse,"r");
   registre2=fopen("LISTE_MOT.txt","w");
do
{
   char* s = {0};
   fgets(s,20,registre);
   fputs(s,registre2);
}while(!feof(registre));
fclose(registre);
fclose(registre2);
}


Je n'ai pas testé l'ouverture des fichiers; mais il n'y a pas de raison. Dois je fais un calloc au niveau du fgets ? Je suis pas vraiment sur de comment marche la fonction.
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

Avatar de l’utilisateur
fatal_error
Membre Légendaire
Messages: 6610
Enregistré le: 22 Nov 2007, 12:00

par fatal_error » 09 Déc 2013, 23:02

si tu sais pas comment marche fgets, qqpart, c'est bien parce que tu as identifié que tu sais pas comment elle marche.
Maintenant si tu sais pas comment elle marche, ben cherches comment elle marche!

Tu as des tas d'exemples sur le net.
http://www.tutorialspoint.com/c_standard_library/c_function_fgets.htm
la vie est une fête :)

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

par ampholyte » 09 Déc 2013, 23:10

Tu ne testes pas l'ouverture d'un fichier, c'est la première raison qui peut te provoquer un problème. Qu'est-ce qui se passe si un fichier est pas ouvert, ou non trouvé car par le bon chemin ? Et bien on continue et on essaye de lire ce qui se trouve dans NULL => segfault

Seconde erreur, tu n'alloues toujours pas ton pointeur char *s.

Personnellement lorsque j'utilise fgets, je préfère déclarer un tableau de char plutôt qu'un pointeur.

Code: Tout sélectionner
char buffer[255 + 1] = {0};

while (fgets(buffer, 255, registre) != NULL) {
    fputs(buffer, registre2);
}


Ici écrire :
Code: Tout sélectionner
char *s = {0};
ne te donne pas de place.

Essaye de faire attention à ce que tu écris.

Soit tu écris :
Code: Tout sélectionner
char *s = NULL;
s = calloc(255 + 1, sizeof(char));
if (s == NULL) {
    printf("error\n");
}

/* reste du code */
free(s);
s = NULL;


Soit
Code: Tout sélectionner
char s[255 + 1] = {0};

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

par Rockleader » 09 Déc 2013, 23:21

fatal_error a écrit:si tu sais pas comment marche fgets, qqpart, c'est bien parce que tu as identifié que tu sais pas comment elle marche.
Maintenant si tu sais pas comment elle marche, ben cherches comment elle marche!

Tu as des tas d'exemples sur le net.
http://www.tutorialspoint.com/c_standard_library/c_function_fgets.htm



Disons que j'ai eu les infos en faisant un man fgets pour la structure.

Seconde erreur, tu n'alloues toujours pas ton pointeur char *s.


Oki; je supposais bien qu'il fallait faire ça, mais je n'en étais pas sur; maintenant c'est chose faite.

Personnellement lorsque j'utilise fgets, je préfère déclarer un tableau de char plutôt qu'un pointeur.


Je suis mal placé pour être tatillon; mais lorsque j'écris:

char* s

Cela revient à char s[] non ?

J'aurais donc pour ma part plutôt tendance à choisir de faire une allocation dynamique avec calloc et un pointeur, peut être à tord.
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

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

par ampholyte » 09 Déc 2013, 23:39

Rockleader a écrit:Cela revient à char s[] non ?

J'aurais donc pour ma part plutôt tendance à choisir de faire une allocation dynamique avec calloc et un pointeur, peut être à tord.


Attention de ne pas confondre char *, char [], et char [255 + 1].

char *ptr = NULL est un pointeur sur char pointant sur NULL
char buffer[] = "tableau" est un tableau de char de taille 7 + 1 initialisé à "tableau"
char buffer[255 + 1] = {0} est un tableau de 255 + 1 initialisé avec des 0 partout

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

par Rockleader » 09 Déc 2013, 23:46

Ce que je veux dire c'est qu'en mettant un pointeur; on travaille sur une valeur, la première d'un tableau par exemple; grâce à laquelle nous pouvons retrouver les autres valeurs du tableau.

Mais si tu utilises un tableau buffer [n+1]; tu es limité à n; alors que si tu utilise un pointeur *buffer; tu peux compléter par le nombre que tu veux non ?
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

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

par ampholyte » 09 Déc 2013, 23:54

Et bien non, l'utilisation des pointeurs est très très dangereux si tu ne fais pas attention à ce que tu fais (bon j'exagère un peu mais bon c'est pour le côté dramatique :D).

Un pointeur te renvoie l'adresse de la case pointée. Si tu pointes vers une case non allouée, cela signifie que lors d'une écriture, tu peux écrire dans la zone mémoire d'un autre programme. Cela pourra donc provoquer des bugs dans ton programme et également dans l'autre programme puisque tu vas venir écraser ce qui se trouve à l'endroit où pointe le pointeur.

C'est pour cette raison qu'il est nécessaire de placer ces pointeurs sur des zones qui sont allouées (qui sont donc spécialement réservés à ton programme).

Lorsque tu écris :
Code: Tout sélectionner
char *s = calloc(20 + 1, sizeof(char));


Tu places le pointeur s sur le premièr élément d'une nouvelle zone allouée de 21 cases.

Lorsque tu écris :
Code: Tout sélectionner
char buffer[20 + 1] = {0};


Tu réserves 21 cases en mémoire.

Dans tous les cas tu es obligé de fixer un maximum lors d'une allocation ou initialisation.

Il existe une fonction de réallocation (realloc) si tu as besoin d'augmenter la taille de la zone allouée par ton pointeur (mais bon ce n'est pas encore ton cas).

Enfin pour te donner une nouvelle indication sur fgets : fgets va lire uniquement le nombre de caractère passé en paramètre. Cela signifie que si ta ligne est supérieur à 20, alors la suite sera lu dans la prochaine tour de boucle.

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

par joel76 » 10 Déc 2013, 00:00

ampholyte a écrit:Enfin pour te donner une nouvelle indication sur fgets : fgets va lire uniquement le nombre de caractère passé en paramètre. Cela signifie que si ta ligne est supérieur à 20, alors la suite sera lu dans la prochaine tour de boucle.
fgets lit au plus le nombre de caractères passés en n'oubliant pas le zéro :lol3:

Je suis mal placé pour être tatillon; mais lorsque j'écris:

char* s

Cela revient à char s[] non ?
Non, dans le premier cas s est contiendra une adresse modifiable éventuellement plus tard.
Dans le second cas, s doit être initialisé au moment de la déclaration char s[] = "toto"; et n'est plus modifiable ensuite (on ne pourra plus modifier s en faisant s = "blabla", on pourra éventuellement, suivant les compilos, modifier le contenu s[0], ou s[1] ou .. jusqu'à s[4], mais attention, s[4] contient le zéro terminal de "toto").

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

par ampholyte » 10 Déc 2013, 00:03

joel76 a écrit:fgets lit au plus le nombre de caractères passés en n'oubliant pas le zéro :lol3:


Oui tout à fait, j'aurais pu l'indiquer, merci =).

Avatar de l’utilisateur
fatal_error
Membre Légendaire
Messages: 6610
Enregistré le: 22 Nov 2007, 12:00

par fatal_error » 10 Déc 2013, 07:22

Dans le second cas, s doit être initialisé au moment de la déclaration char s[] = "toto"; et n'est plus modifiable ensuite (on ne pourra plus modifier s en faisant s = "blabla", on pourra éventuellement, suivant les compilos, modifier le contenu s[0], ou s[1] ou .. jusqu'à s[4], mais attention, s[4] contient le zéro terminal de "toto").

s n'est plus modifiable? ah bon?
la vie est une fête :)

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

par ampholyte » 10 Déc 2013, 08:53

fatal_error a écrit:s n'est plus modifiable? ah bon?


Je confirme ce que fatal_error souhaite indiquer.

Lorsque tu écris
Code: Tout sélectionner
char s[] = "toto";


Rien ne t'empêche de faire par exemple :

Code: Tout sélectionner
int i = 0;
for (i = 0; i < strlen(s); i++) {
    s[i] = 'a';
}


et ceci avec n'importe quel compilo.

En revanche tu ne pourras en effet pas écrire
Code: Tout sélectionner
s = "tata"
en C (sauf lors de la déclaration de ta variable)

Tu peux donc modifier la chaine de caractère.

Pour bloquer une chaine de caractère, il faut rajouter le mot clef const devant la déclaration.

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

par Rockleader » 10 Déc 2013, 16:39

Je m'attaque à mon projet de fin de semestre en algo (simulation d'un système raid5 simplifié) ça à l'air d'être assez chaud tout ça...


On nous as donné un fichier.h contenant quelques fonctions et constantes; entre autre des structures.

Or je n'ai pas reconnu cette syntaxe de structure

Code: Tout sélectionner
typedef struct inode_s{
  char filename[FILENAME_MAX_SIZE];
  uint size;
  uint nblock; // nblock = (size+BLOCK_SIZE-1)/BLOCK_SIZE
  uint block_id;
} inode_t;


Il y a un nom avant et après la structure; inode_s et inode_t
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

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

par ampholyte » 10 Déc 2013, 16:53

Lorsque tu construis une structure normalement tu procèdes comme ceci :

Code: Tout sélectionner
struct ma_struct {

};


Tu rajoutes souvent un typedef pour éviter de réécrire tout le temps le mot struct
Code: Tout sélectionner
typedef struct ma_struct nouveau_nom;


En simplifiant on écrit donc :
Code: Tout sélectionner
typedef struct {

} ma_struct;


ou
Code: Tout sélectionner
typedef struct ma_struct {
};


Ici tu es dans le dernier cas c'est à dire que tu créés une structure du type "struct inode_s" que tu renommes en inode_t.

Tu devras donc dans ton programme appeler cette structure à l'aide d'un "inode_t toto;"

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

par Rockleader » 10 Déc 2013, 16:57

Donc si j'ai bien compris; cela permet de remplacer

struct inode_s par inode_t ???
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

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

par ampholyte » 10 Déc 2013, 16:59

Rockleader a écrit:Donc si j'ai bien compris; cela permet de remplacer

struct inode_s par inode_t ???


Tout à fait.

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

par Rockleader » 10 Déc 2013, 17:02

Oki; je viens de démystifier une bonne partie des notations du sujets avec ça déjà =) Le reste c'est de la compréhension de ce que ça doit faire un RAID5

Merci.

Reste à se mettre au boulot ;)
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

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

par Rockleader » 10 Déc 2013, 19:55

Une autre question; est ce possible de "lier" deux fichiers headers ? En fait peut on avoir autant de headder et fichier c associé pour un seul et unique programme principal ?
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

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

par Rockleader » 10 Déc 2013, 21:49

AUtre chose; dans une structure j'ai ceci:

Code: Tout sélectionner
FILE ;)storage [ NUMBER OF DISKS ]


Normalement on effectue un FILE *controle_adresseFichier

ça ne gène pas si on ne met pas une chaîne de contrôle comme lorsque je faisais FILE *registre ?


EN fait ici si j'ai bien compris on aurait une chaine de controle par disque (représenté par des fichiers)

Je sais pas si je suis très clair dans ma question è_é
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

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

par ampholyte » 10 Déc 2013, 22:17

Rockleader a écrit:Une autre question; est ce possible de "lier" deux fichiers headers ? En fait peut on avoir autant de headder et fichier c associé pour un seul et unique programme principal ?


Tout à fait, tu peux avoir plusieurs headers et plusieurs sources pour un même programme. C'est d'ailleurs très souvent le cas dans un projet =).


AUtre chose; dans une structure j'ai ceci:

Code:

FILE ;)storage [ NUMBER OF DISKS ]



Normalement on effectue un FILE *controle_adresseFichier

ça ne gène pas si on ne met pas une chaîne de contrôle comme lorsque je faisais FILE *registre ?


EN fait ici si j'ai bien compris on aurait une chaine de controle par disque (représenté par des fichiers)

Je sais pas si je suis très clair dans ma question è_é



Rien de compliquer là dedans.

Lorsque tu déclares un pointeur de type FILE tu écris :
Code: Tout sélectionner
FILE *file = NULL;


Lorsque tu déclares un tableau de pointeur de type int tu écris :
Code: Tout sélectionner
int tab[10] = {0};


Lorsque tu déclares un tableau de pointeur de type FILE tu écris :
Code: Tout sélectionner
FILE *tab[10];


Donc par exemple si je veux ouvrir un fichier je vais écrire :
Code: Tout sélectionner
tab[i] = fopen(PATH, "r+");


Cela va te permettre de stocker plusieurs fichiers dans une même variable (tableau) =)

 

Retourner vers ϟ Informatique

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 10 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