1
votes

impossible d'accéder à une place dans la mémoire

J'essaye de lire un fichier binaire de 32 octets en C, mais j'obtiens toujours un "défaut de segmentation (code dumpé)" lorsque j'exécute mon programme, ce serait formidable si quelqu'un peut m'aider en indiquant où je me suis trompé ?. mon code est ici ci-dessous:

int main()
{


   char *binary = "/path/to/myfiles/program1.ijvm";
   FILE *fp;
   char buffer[32];

   // Open read-only
   fp = fopen(binary, "rb");

   // Read 128 bytes into buffer
   fread (buffer, sizeof(char), 32, fp);



   return 0;
 }


4 commentaires

il est temps de vérifier les codes d'erreur, probablement fp est nul (l'activation des avertissements BTW au moment de la compilation vous indiquerait également des problèmes potentiels ...)


Vous lisez 32 octets, pas 128


Veuillez ne pas répéter dans le commentaire ce qui est écrit dans le code. Cela conduit à ce que nous voyons ici: les commentaires avec des littéraux sont presque toujours faux. ;-)


Si l'une de ces réponses est utile, veuillez la voter et / ou l'accepter comme réponse. Aussi, avez-vous compris le problème?


3 Réponses :


1
votes

C'est à cause du chemin. Assurez-vous que "/path/to/myfiles/program1.ijvm" pointe vers un fichier existant. Vous devez toujours vérifier la valeur de retour de fopen .

\\Open read-only
fp = fopen(binary, "rb");
if(fp==NULL){
    perror("problem opening the file");
    exit(EXIT_FAILURE);
}

Notez également que vous lisez 32 octets dans votre tampon et non 128 comme le dit votre commentaire.


0 commentaires

1
votes

Vous devez vérifier le résultat de retour de fopen () .

Je suppose que vous obtenez le segfault dans fread () code> parce que votre fichier de données n'existe pas, ou n'a pas pu être ouvert, et que vous essayez de travailler sur une structure NULL FILE.

Voir le code sécurisé suivant:

FILE *fp = fopen(.....);

Lorsque j'exécute ce code, il ne plante pas et affichera le nombre d'éléments lus si le fichier est ouvert ou il affichera "Impossible d'ouvrir le fichier" si le fichier n'a pas pu être ouvert.

Comme mentionné dans les commentaires, vous devez également fermer le fichier en cours de fermeture. Une autre chose que vous pouvez faire est la suivante:

#include <stdio.h>
#include <stdint.h>

#define SIZE_BUFFER      32

int main()
{
   char *binary = "data.txt";
   FILE *fp = NULL;
   char buffer[SIZE_BUFFER];

   // Open read-only
   fp = fopen(binary, "rb");

   // Read SIZE_BUFFER bytes into buffer
   if( fp )
   {
        printf("Elements read %ld\n", fread (buffer, sizeof(char), SIZE_BUFFER, fp));
        fclose(fp);
   }
   else
   {
        // Use perror() here to show a text description of what failed and why
        perror("Unable to open file: ");
   }
   return 0;
 }

Au lieu de déclarer et d'attribuer en deux étapes distinctes.


16 commentaires

Il doit également fermer le dossier avant de retourner


Pourquoi devez-vous initialiser fp à NULL ? Qu'en est-il des choses comme FILE * fp = fopen ("/ foo / bar / baz.quux"); ?


@EdwardMinnix Bien sûr, vous pouvez faire l'ouverture et l'affectation de fp sur la même ligne.


@Chimera Alors pourquoi devez définir fp sur NULL? Tant que fp est inconditionnellement défini sur le résultat de fopen (3) , peu importe ce à quoi il était initialement lié.


@EdwardMinnix Avez-vous lu ma réponse où j'ai dit "Notez également que c'est une bonne idée d'initialiser FILE * fp à NULL. Sur ma machine, si je ne faisais pas cela et que le fichier n'était pas ouvert, il planterait toujours."


fp n'a pas besoin d'être initialisé. Il est défini plus tard avant d'être utilisé. C'est acceptable. Si elle était utilisée avant d'être utilisée, cela poserait un problème


@Chimera, oui mais la deuxième phrase de votre réponse est De plus, vous devez initialiser fp à null. Le code suivant est sûr. Je ne suis pas sûr que vous affirmiez s'il s'agit d'un doit ou d'un devrait . De plus, je ne comprends pas pourquoi il est dangereux de ne pas initialiser fp lorsque vous l'affectez immédiatement, d'autant plus que man 3 fopen indique clairement que ce ne sera que non- null s'il a été ouvert avec succès. Si vous ne l'utilisez pas avant de l'attribuer, je ne vois pas en quoi ce serait un problème.


@EdHeal C'est ce que vous penseriez. Toutefois. sur ma machine et mon compilateur, si je n'initialise pas fp à null, le programme échoue si le fichier n'est pas ouvert.


@EdwardMinnix Ok, c'est un must.


Il est recommandé d'initialiser toutes vos variables lorsque vous les déclarez, peu importe.


L'expérience de pensée FILE * fp; - fp peut être n'importe quoi. Le programme se poursuit. La prochaine fois que fp sera utilisé, c'est ici fp = fopen .... - Maintenant, fp a une valeur. Une fois que cela est dangereux, la valeur de fp est traitée correctement


@EdHeal OUI! C'est ainsi que cela devrait fonctionner. Mais ce n'est pas ce que mon compilateur / bibliothèque std a DID.


Désolé mais cette instruction Notez également que c'est une bonne idée d'initialiser FILE * fp à NULL. Sur ma machine, si je ne faisais pas cela et que le fichier n'était pas ouvert, il planterait toujours. est faux. fp sera défini sur NULL en cas d'impossibilité d'ouvrir le fichier - selon le manuel,


@EdHeal Aimeriez-vous voir comment mon compilateur / bibliothèque a échoué lors de cette expérience? Je peux vous montrer.


@EdHeal Je viens de refaire mon test. Je dois tester de manière incorrecte. Je viens de mettre à jour ma réponse. Je pensais que c'était bizarre que je doive initialiser fp. Je ne sais pas comment j'ai fait un mauvais test. :-(


@Chimera - Pas de soucis - Cela arrive au meilleur d'entre nous



0
votes

Il y a deux raisons possibles

  1. La fonction fopen (3) a échoué pour une raison quelconque, ce qui signifie que fp est NULL, puis vous essayez d'utiliser le pointeur nul dans fread (3) . Cela peut planter. @OznOg a déjà donné une astuce subtile pour regarder dans cette direction.
  2. Si l'appel fopen est un succès (c'est-à-dire que fp est non NULL après avoir appelé fopen ), le code peut toujours planter car vous lisent 32 caractères dans la variable binary , tandis que binary a été initialisé avec seulement 30 caractères.

3 commentaires

Mais il a déclaré char binary [32] , pas binary [30]


La taille du tampon n'est PAS le problème. C'est exactement la taille du nombre d'octets lus. Le problème est certainement que le fichier n'est pas ouvert, laissant fp nul.


merci EdwardMinnix et Chimera pour vos commentaires. Il a édité son code après avoir posté mes commentaires, d'où cette divergence ou confusion. Auparavant, c'était quelque chose comme 'char * buffer = "/path/to/myfiles/program1.ijvm" qui est également mentionné dans l'autre réponse à cette question par gerardo