2 votes

Une erreur concernant "L'adresse 0x0 n'est pas stack'd, malloc'd ou (récemment) free'd" dans un programme C sous l'environnement Linux

[Edit1:]

Pour le seqName, je le déclare comme un paramètre global au début du fichier comme

char seqName[20];

[Edit2:]

Ne sont-ce pas les nombres passés au programme lors de l'exécution réelle? J'ai reçu le message suivant juste en utilisant l'outil valgrind. La commande que j'ai entrée est:

jl@ubuntu:~/work/dsr_analysis$ valgrind --tool=memcheck --leak-check=yes ./test

[Edit3:]

Désolé, étant donné que je suis un nouvel utilisateur de Valgrind, lorsque je l'utilise, je saisis uniquement la commande de l'Edit2.

Cependant, mon programme a bel et bien des paramètres en ligne de commande.

Par conséquent, je pense qu'il vaut mieux déboguer mon programme avec la nouvelle commande:

valgrind --tool=memcheck --leak-check=yes ./test foreman.cif 352 288


Voici un morceau de mon programme:

height = atoi(argv[3]);

width = atoi(argv[2]);

sprintf(seqName,"%s", argv[1]);

// strcpy(seqName, argv[1]);

Après l'avoir compilé, un fichier exécutable test est généré, puis j'utilise Valgrind pour le vérifier. Ensuite, j'ai reçu le message suivant, cependant je ne comprends pas ce qu'il essaie de me dire. Quelqu'un pourrait-il apporter un peu d'aide, merci.

jl@ubuntu:~/work/dsr_analysis$ valgrind --tool=memcheck --leak-check=yes ./test

\==28940== Memcheck, un détecteur d'erreurs de mémoire

\==28940== Copyright (C) 2002-2009, et GNU GPL'd, par Julian Seward et al.

\==28940== En utilisant Valgrind-3.6.0.SVN-Debian et LibVEX;

relancer avec -h pour les infos de copyright

\==28940== Commande : ./test

\==28940==

\==28940== Lecture invalide de taille 1

\==28940== à 0x40260CA: strcpy (mc_replace_strmem.c:311)

\==28940== par 0x804A5C6: main (me_search.c:1428)

\==28940== L'adresse 0x0 ne se trouve pas dans la pile, allouée par malloc ou (récemment) libérée

\==28940==

\==28940==

\==28940== Processus terminé avec l'action par défaut du signal 11 (SIGSEGV)

\==28940== Accès en dehors de la région mappée à l'adresse 0x0

\==28940== à 0x40260CA: strcpy (mc_replace_strmem.c:311)

\==28940== par 0x804A5C6: main (me_search.c:1428)

\==28940== Si vous pensez que cela s'est produit à la suite d'un débordement de pile dans le thread principal de votre programme (peu probable mais possible), vous pouvez essayer d'augmenter la taille de la pile du thread principal en utilisant le drapeau --main-stacksize=.

\==28940== La taille de la pile du thread principal utilisée dans cette exécution était de 8388608.

\==28940==

\==28940== RÉSUMÉ DU TAS:

\==28940== utilisé à la sortie : 0 octets dans 0 blocs

\==28940== utilisation totale du tas : 0 allocations, 0 libérations, 0 octets alloués

\==28940==

\==28940== Tous les blocs du tas ont été libérés -- aucune fuite possible

\==28940==

\==28940== Pour les comptes des erreurs détectées et supprimées, relancer avec : -v

\==28940== RÉSUMÉ DES ERREURS : 1 erreurs provenant de 1 contexte (supprimé : 13 provenant de 8 contextes)

1 contexte (supprimé : 13 provenant de 8 contextes)

7voto

Vous n'avez vraiment pas posté de code assez clair pour être sûr, mais si vous appelez votre exécutable sans paramètres en ligne de commande, alors argv[1] contiendra un pointeur NULL, et argv[2], argv[3], etc. contiendront des valeurs non définies.

Éditer : Vous devez fournir au programme des paramètres sur la ligne de commande de valgrind (je suppose - je n'utilise pas valgrind moi-même). Quelque chose comme :

valgrind ... ./test foo bar zod

Et au fait, appeler un exécutable test est une mauvaise idée sur Linux/Unix car il est très facile de se perdre avec la commande shell du même nom

2voto

VeeArr Points 3504

Il y a deux choses que vous devriez vérifier :

1) Assurez-vous que vous recevez le bon nombre de paramètres en vérifiant la valeur de argc.

2) Assurez-vous que vous avez utilisé malloc() pour allouer suffisamment d'espace dans seqName avant d'essayer d'utiliser strcpy().

1voto

zed_0xff Points 12379

Vérifiez-vous le nombre réel d'arguments passés à votre programme? (argc)

Si votre programme reçoit moins de 3 arguments et que vous essayez d'accéder à argv[1..3] - vous obtiendrez des erreurs de segmentation et d'autres comportements imprévisibles.

1voto

Zorf Points 2931

Je pense que le point est le suivant: sprintf(seqName,"%s", argv[1])

Et ce que vous voulez réellement est sprintf((strcat(seqName,"%s"), argv[1]) en jugeant votre code.

Ce qu'il essaie de faire ici est de passer la valeur de l'expression "%s" à interpréter dans le format. Cette valeur est spécifiquement un pointeur de caractère vers un '%' en mémoire statique avec un 's' à côté, puis un '\0'.

Modifier, oh attends, laisse tomber, je vois que c'est sprintf, pas printf. Alors c'est probablement le compte des arguments

Modifier2: De plus, est-ce que seqName est correctement initialisé et alloué?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X