Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

écrire fichier segmentation fault ?

23 réponses
Avatar
pere.noel
bon, je continue mes périgrinations C-esques.

je lis un tuto sur le net :
<http://irc.essex.ac.uk/www.iota-six.co.uk/c/i4_fwrite_fscanf_fprintf.as
p>

qui donne le code suivant (au complet) :

--- file.c -------------------------------------------------------------
#include <stdio.h>

int main() {
FILE *sourceFile;
FILE *destinationFile;
char *buffer;
int n;

sourceFile = fopen("file.c", "r");
destinationFile = fopen("file2.c", "w");

if(sourceFile==NULL) {
printf("Error: can't access file.c.\n");
return 1;
}
else if(destinationFile==NULL) {
printf("Error: can't create file for writing.\n");
return 1;
}
else {
n = fread(buffer, 1, 1000, sourceFile); /* grab all the text */
fwrite(buffer, 1, n, destinationFile); /* put it in file2.c */
fclose(sourceFile);
fclose(destinationFile);

destinationFile = fopen("file2.c", "r");
n = fread(buffer, 1, 1000, destinationFile); /* read file2.c */
printf("%s", buffer); /* display it all */

fclose(destinationFile);
return 0;
}
}
------------------------------------------------------------------------

donc ça lit le fichier source "file.c" et ça écrit dans le fichier
destination "file2.c".

mais, au runtime j'ai droit à une "segmentation fault" dont je ne vois
pas la raison...
--
une bévue

10 réponses

1 2 3
Avatar
pere.noel
Eric Levenez wrote:

Il faut apprendre à fermer ce que l'on
a ouvert.


ça c'est sûr !
--
une bévue

Avatar
fagotto
En regle générale les return dans la fonction c'est caca.
Fuites de mémoire assurées
les else sont faits pour ça. Sinon on utilise une variable booleene
qu'on teste pour savoir si on continue le traitement. Quoi qu'il arrive
on sort à la fin en libérant et en fermant tout ce qu'on a réservé et
ouvert. Quand on fait comme ça on risque moins d'oublier quelque chose.
On est prié de laisser cet endroit dans l'état où on l'a trouvé en entrant.

Seule exception que je m'autorise pour les return en cours de fonction
sont les fonctions de description d'enum

const char *
CADbTypeDescription(CADbType type)
{
switch (type) {
case CADbType_Undefined: return "undefined database server type";
case CADbType_Oracle: return "Oracle";
case CADbType_MSSql: return "MSSql";
case CADbType_MySql: return "MySql";
}
caerror(glcore, "Unknown database server type %d", type);
return "unknown database server type";
}




Le 17/09/06 11:35, dans
<1hlt3h3.u6mtczr02lt5N%, « Une bévue »

bon, je continue mes périgrinations C-esques.

je lis un tuto sur le net :
<http://irc.essex.ac.uk/www.iota-six.co.uk/c/i4_fwrite_fscanf_fprintf.as
p>


Mais faut pas lire des choses comme cela !

Cette exemple est ce qu'il NE FAUT PAS FAIRE !

qui donne le code suivant (au complet) :

--- file.c -------------------------------------------------------------
#include <stdio.h>

int main() {


int main(void) {

FILE *sourceFile;
FILE *destinationFile;
char *buffer;


buffer n'est pas initialisé

int n;

sourceFile = fopen("file.c", "r");
destinationFile = fopen("file2.c", "w");

if(sourceFile==NULL) {
printf("Error: can't access file.c.n");
return 1;


return EXIT_FAILURE;

Si le premier fichier n'existe pas mais le second existe, alors on a ouvert
le second, mais on ne l'a pas fermé. Mauvais.

}
else if(destinationFile==NULL) {


Le "else" est inutile à cause du return précédent

printf("Error: can't create file for writing.n");
return 1;


return EXIT_FAILURE;

Il faudrait fermer là le premier fichier au lieu de le laissé ouvert

}
else {


Le "else" est inutile à cause du return précédent

n = fread(buffer, 1, 1000, sourceFile); /* grab all the text */


On lit 1000 char dans un buffer qui n'a pas été alloué, d'où plantage

"n" n'est pas testé pour savoir si on a eu une erreur.

fwrite(buffer, 1, n, destinationFile); /* put it in file2.c */


On écrit ce qu'on a lu (si on a eu la chance de ne pas avoir d'erreur), mais
on ne vérifie pas si on a bien écrit.

fclose(sourceFile);
fclose(destinationFile);

destinationFile = fopen("file2.c", "r");


On ne teste pas le code de retour de fopen

n = fread(buffer, 1, 1000, destinationFile); /* read file2.c */


On lit des données (si on n'a pas d'erreur) dans un buffer non alloué

printf("%s", buffer); /* display it all */


Il faudrait faire un fflush(stdout) pour être sûr que les caractères
bufferisés sont bien envoyé (même si exit le fait normalement).

fclose(destinationFile);


Si le fopen a raté, alors il ne faut pas faire le flcose

return 0;
}
}
------------------------------------------------------------------------

donc ça lit le fichier source "file.c" et ça écrit dans le fichier
destination "file2.c".


Donc ce code fait n'importe quoi.

mais, au runtime j'ai droit à une "segmentation fault" dont je ne vois
pas la raison...


C'est un jeu des 1000 erreurs ?




Avatar
Harpo
fagotto wrote:

En regle générale les return dans la fonction c'est caca.
Fuites de mémoire assurées


Ca se discute.

les else sont faits pour ça. Sinon on utilise une variable booleene
qu'on teste pour savoir si on continue le traitement.


Ca complique donc la fonction pour se complier à une certaine
réglementation qu'on s'impose.

int
f(int x, int y) {
if (x == 0) return 0;
if (y == 0) return 0;
if (y > 0) return x / y;
if (x > 0) return y/x;
return 1;
}

Quelle que soit l'inutilité de cette fonction, elle me semble plus
facilement compréhensible que :

int
f(int x, int y) {
int ret;
if (x == 0) {
ret = 0;
}
else {
if (y == 0) {
ret = 0;
}
else {
if (y > 0) {
ret = x / y;
}
else {
if (x > 0) {
ret = y / x;
}
else {
ret = 1;
}
}
}
}
return ret;
}

Pour moi, yapafoto.

--
http://patrick.davalan.free.fr/

Avatar
Pierre Maurette
fagotto wrote:

En regle générale les return dans la fonction c'est caca.
Fuites de mémoire assurées


Ca se discute.

les else sont faits pour ça. Sinon on utilise une variable booleene
qu'on teste pour savoir si on continue le traitement.


Ca complique donc la fonction pour se complier à une certaine
réglementation qu'on s'impose.

int
f(int x, int y) {
if (x == 0) return 0;
if (y == 0) return 0;
if (y > 0) return x / y;
if (x > 0) return y/x;
return 1;
}

Quelle que soit l'inutilité de cette fonction, elle me semble plus
facilement compréhensible que :

int
f(int x, int y) {
int ret;
if (x == 0) {
ret = 0;
}
else {
if (y == 0) {
ret = 0;
}
else {
if (y > 0) {
ret = x / y;
}
else {
if (x > 0) {
ret = y / x;
}
else {
ret = 1;
}
}
}
}
return ret;
}

Pour moi, yapafoto.


Je suis bien d'accord, dans certains cas loin d'être rares la structure
d'une fonction induit tellement le return multiple que je ne vois pas
pourquoi s'en passer. Dans certains cas on pourrait utiliser un switch
... case, mais il est très rudimentaire en C.

Sinon, j'aime bien, avec en prime uns seul return:

int f(int x, int y) {
return (x == 0)||(y == 0) ? 0 : y > 0 ? x / y : x > 0 ? y / x : 1;
}

Les plus timides peuvent parenthéser / indenter.

--
Pierre Maurette


Avatar
Sylvain
Pierre Maurette wrote on 30/09/2006 14:08:

Sinon, j'aime bien, avec en prime uns seul return:

int f(int x, int y) {
return (x == 0)||(y == 0) ? 0 : y > 0 ? x / y : x > 0 ? y / x : 1;
}


c'est encore trop ;)

return (x * y) ? y > 0 ? x / y : x > 0 ? y / x : 1 : 0;

Sylvain.

Avatar
Xavier Roche
c'est encore trop ;)
return (x * y) ? y > 0 ? x / y : x > 0 ? y / x : 1 : 0;


Horreur, une multiplication de deux int superflue.

Avatar
Pierre Maurette
c'est encore trop ;)
return (x * y) ? y > 0 ? x / y : x > 0 ? y / x : 1 : 0;


Horreur, une multiplication de deux int superflue.


return (x | y) ? y > 0 ? x / y : x > 0 ? y / x : 1 : 0;

Mais je n'aime pas.

--
Pierre Maurette


Avatar
Sylvain
Xavier Roche wrote on 30/09/2006 15:56:

return (x * y) ? y > 0 ? x / y : x > 0 ? y / x : 1 : 0;


Horreur, une multiplication de deux int superflue.


les grands mots t'suite ... un OU est plus économe soit.

Sylvain.


Avatar
Harpo
Pierre Maurette wrote:

Sinon, j'aime bien, avec en prime uns seul return:

int f(int x, int y) {
return (x == 0)||(y == 0) ? 0 : y > 0 ? x / y : x > 0 ? y / x : 1;
}

Les plus timides peuvent parenthéser / indenter.


Parenthésage et indentage sont les 2 mammelles de la lisibilité.

--
http://patrick.davalan.free.fr/

Avatar
Pierre Maurette
Pierre Maurette wrote:

Sinon, j'aime bien, avec en prime uns seul return:

int f(int x, int y) {
return (x == 0)||(y == 0) ? 0 : y > 0 ? x / y : x > 0 ? y / x : 1;
}

Les plus timides peuvent parenthéser / indenter.


Parenthésage et indentage sont les 2 mammelles de la lisibilité.


La lisibilité serait donc mammifère ?

Tiens, savez-vous pourquoi les coqs n'ont pas de mains ?

--
Pierre Maurette


1 2 3