Adresse 0x0 n'est pas pile d, malloc d or (récemment) libre avais
Je suis très novice en C, et n'arrive pas à comprendre quel est le problème avec le code suivant.
int main() {
char filen[] = "file.txt";
FILE *file = fopen ( filen, "r" );
if ( file != NULL )
{
char line [ 128 ];
while ( fgets ( line, sizeof line, file ) != NULL ) /* read a line */
{
int i;
char *result;
for(i=0; i< NUM;i++)
{
char *rep;
rep = (char *) malloc (sizeof(mychars[i][0]));
strcpy(rep, mychars[i][0]);
char *with;
with = (char *) malloc (sizeof(mychars[i][1]));
strcpy(with, cgichars[i][1]);
result = (char *) malloc (sizeof(char) * 128);
result = str_replace(line, rep, with);
}
fputs(result, stdout);
}
}
fclose ( file );
return 0;
}
Valgrind me donne cette erreur:
==4266== Invalid read of size 1
==4266== at 0x4C286D2: __GI_strlen (mc_replace_strmem.c:284)
==4266== by 0x5118A8D: fputs (iofputs.c:37)
==4266== by 0x400A0F: main (repl.c:35)
==4266== Address 0x0 is not stack'd, malloc'd or (recently) free'd
repl.c correspond à la ligne commençant avec fputs vers la fin de ce code.
Aussi, mychars est un tableau à deux dimensions qui ressemble à ceci:
char *mychars[NUM][2] = {
"a", "97",
"b", "98",
....
Quelqu'un peut-il me dire comment résoudre ce problème? Aussi, tous les pointeurs sur comment je dois améliorer mon code actuel (surtout avec malloc) serait très appréciée.
Edit: Code pour str_replace
char *str_replace(char *str, char *orig, char *rep) {
char buffer[4096];
char *p;
if(!(p = strstr(str, orig)))
return NULL;
strncpy(buffer, str, p-str);
buffer[p-str] = 'char *str_replace(char *str, char *orig, char *rep) {
char buffer[4096];
char *p;
if(!(p = strstr(str, orig)))
return NULL;
strncpy(buffer, str, p-str);
buffer[p-str] = '\0';
sprintf(buffer+(p-str), "%s%s", rep, p+strlen(orig));
return buffer;
}
';
sprintf(buffer+(p-str), "%s%s", rep, p+strlen(orig));
return buffer;
}
EDIT 2 Nouveau Code pour str_replace, et les principaux
Des fins de test, j'ai remplacé mon str_replace méthode avec celle trouvée ici:
Quelle est la fonction de remplacer la chaîne de caractères en C?
Et mon principal est légèrement modifié:
int main() {
static const char filen[] = "file.txt";
FILE *file = fopen ( filen, "r" );
if ( file != NULL )
{
char line [ 128 ];
while ( fgets ( line, sizeof line, file ) != NULL ) /* read a line */
{
int i;
char *result;
for(i=0; i< NUM;i++)
{
char *rep;
rep = (char *) malloc (sizeof(mychars[i][0]));
strcpy(rep, mychars[i][0]);
char *with;
with = (char *) malloc (sizeof(mychars[i][1]));
strcpy(with, mychars[i][1]);
result = str_replace(line, rep, with);
}
fputs(result, stdout);
}
}
fclose ( file );
return 0;
}
Mais je suis encore en train
==6730== Invalid read of size 1
==6730== at 0x4C286D2: __GI_strlen (mc_replace_strmem.c:284)
==6730== by 0x5118A8D: fputs (iofputs.c:37)
==6730== by 0x400995: main (repl.c:29)
==6730== Address 0x0 is not stack'd, malloc'd or (recently) free'd
Peut-être la partie la plus frustrante de ce n'est pas de savoir ce ces Invalides, des erreurs de lecture sont.
EDIT 3
J'ai mis à jour le code dans le centre de la boucle tant que tel:
int i;
char* result;
result = &line[0];
for(i=0; i< NUM_CGICHARS;i++)
{
char *rep;
rep = (char *) malloc (sizeof(char));
strcpy(rep, cgichars[i][1]);
char *with;
with = (char *) malloc (sizeof(char)*3);
strcpy(with, cgichars[i][0]);
result = str_replace(result, rep, with);
fputs(result, stdout);
free(rep);
free(with);
}
Et maintenant je commence à être de sortie! Cependant, après seulement deux itérations, j'obtiens une erreur de segmentation, avec valgrind de me donner tout un tas de ceci:
==9130== Invalid read of size 1
==9130== at 0x4C286D2: __GI_strlen (mc_replace_strmem.c:284)
==9130== by 0x5118A8D: fputs (iofputs.c:37)
==9130== by 0x4009DF: main (teststep1.c:27)
==9130== Address 0x0 is not stack'd, malloc'd or (recently) free'd
OriginalL'auteur varatis | 2012-04-12
Vous devez vous connecter pour publier un commentaire.
Dans ces deux lignes
vous d'abord allouer de l'espace pour
result
que vous, alors lâche immédiatement après en les écrasant avec le retour destr_replace
. Cette fonction renvoie probablement0
, de sorte que votrefputs
échoue.BTW, ne jette pas le retour de
malloc
, C ce qui est superflu et peut cacher le fait que vous avez oublié d'inclure le prototype.Edit: Votre
str_replace
la fonction est complètement fausse dans sa gestion de la mémoire. Jamais renvoient un pointeur sur une variable locale, l'espace n'est pas valide après avoir quitté la fonction.pour
str_replace
voir mon edit. Pour la logique de votre programme, j'ai du mal à comprendre ce que vous voulez atteindre. Pourquoi êtes-vous allouer quelque chose à l'intérieur de la boucle, puis l'effacer, et où vous avez juste serait d'utiliser la dernière valeur affectée à lafputs
?Je suis en train de lire un fichier ligne par ligne, et pour chaque ligne, remplacer certains caractères de la ligne, avec des chaînes de caractères spécifié par mychars
Jens, j'ai remplacé mon str_replace méthode avec celle que l'on trouve dans le lien dans le menu edition, afin que je puisse correctement debug ma fonction main (). Cependant, je suis encore en train une erreur similaire.
vous devriez couper votre problème dans les plus petites. Ne pas essayer de faire plusieurs remplacements dans un
for
boucle pour le moment, et ce pour plusieurs lignes, ce qui est beaucoup trop complexe. Viens de faire un tel remplacement sansfor
etwhile
boucle et essayez d'afficher le résultat. En fait, le remplacement est déjà le mauvais terme, puisque vous ne serez pas en mesure de faire simple remplacement de caractères, votre source et cible les chaînes semblent être de longueur différente.OriginalL'auteur Jens Gustedt
Si
NUM
est 0, alorsresult
est initialisé et peut être0
par hasard.Vous n'êtes pas de vérifier les résultats de vos appels à
malloc()
, de sorte qu'un échec peut signifier que vous essayez d'écrire dans unNULL
pointeur.Où est
mychars
déclaré?malloc
retourNULL
est très rare de nos jours, surtout avec les systèmes d'exploitation qui mettent en œuvre la mémoire overcommitting.wtf!?
Recherche de "surcharge de mémoire" et "oom killer". Un certains systèmes, si vous demandez à la mémoire de
malloc
(plus que ce qui est disponible),malloc
renverra un pointeur valide (adresse virtuelle), et il ne causera pas de problèmes jusqu'à ce que vous fait écrire à chaque page. Une fois que vous avez besoin d'écrire une page de mémoire que le système d'exploitation n'ont pas, la OOM Killer va tuer les processus basés sur un système de priorité pour libérer plus de pages pour vous écrire. Bien que, l'OOM Killer peut tuer votre propre processus, s'il le juge "faible priorité".Ici une meilleure explication à ce sujet
OriginalL'auteur Graham Borland
Vous n'avez pas de montrer comment
mychars
est déclaré, mais cette ligne:dirait probablement qu'elle n'alloue un octet. Aussi, vous êtes à allouer beaucoup de mémoire et de ne jamais en le libérant. Et ici:
Allouer de la mémoire à l'aide de
malloc
, puis complètement à jeter le pointeur de la mémoire par l'affectation de la valeur de retour d'une autre fonction sur le dessus de lui.OriginalL'auteur dreamlax