3 votes

corruption du tas détectée après un bloc normal(#174)

Je sais que cette question a déjà été posée mais je n'ai pas réussi à réparer mon programme.

  void swap1(char*str1,char*str2)
{
    char *ezer =new char[strlen(str1)];
    for (int i = 0 ; i <= strlen(str1);i++)
        ezer[i]=str1[i];
    delete [] str1;
    str1= new char[strlen(str2)];
    for (int i = 0 ; i <= strlen(str2);i++)
        str1[i]=str2[i];
    delete [] str2;
    str2= new char[strlen(ezer)];
    for (int i = 0 ; i <= strlen(ezer);i++)
        str2[i]=ezer[i];
    delete[] ezer;
}

une fois, la première fois, ça marche, mais la deuxième fois (avec une autre valeur), j'ai une erreur. l'erreur vient de la dernière ligne delete[] ezer; pourquoi je ne peux pas supprimer ezer ?

l'erreur :

heap corruption detected after normal block (#174) at 0x007D7A48
CRT detected that the application wrote to memory end of heap buffer

5voto

Ron Dahlgren Points 1524

Strlen ne compte pas le terminateur nul à la fin de vos chaînes de caractères. Cela signifie qu'après une application de votre fonction swap, les deux chaînes seront échangées, mais ne seront plus terminées par un caractère nul. Le comportement de strlen sur une chaîne sans terminaison nulle est indéfini, ce qui signifie que vous vous trouvez en dehors des limites du tas alloué lorsque vous parcourez une de ces chaînes massacrées.

Les chaînes de caractères en C sont représentées comme un pointeur de caractères avec un octet à valeur nulle indiquant la fin de la chaîne (le terminateur nul dont j'ai parlé). Toute routine de la bibliothèque qui opère sur des "chaînes" s'attend à recevoir un tableau de caractères dont la fin est marquée par null, et aura un comportement non défini dans le cas contraire (puisque vous fournirez un tableau de caractères, et non une chaîne de caractères à ce moment-là).

Utilisez la fonction de la bibliothèque strcpy au lieu de développer la vôtre.

Ver cette question pour les détails.

0voto

alk Points 26509

Vous manquez d'allouer de l'espace pour le 0-terminator ici :

char *ezer = new char[strlen(str1)];

Changez ça en :

char *ezer = new char[strlen(str1) + 1];

La véritable (première) corruption de mémoire se produit ici :

  for (int i = 0 ; i <= strlen(str1);i++)
    ezer[i]=str1[i];

Comme avec la dernière itération (celle qui copie le terminateur 0) ezer[i] se réfère à la mémoire "juste derrière" ce qui a été alloué pour ezer .

Refaites la même chose pour les deux autres allocations du tableau de caractèresyc.

Quoi qu'il en soit, comme cela corrigerait la corruption du tas, la fonction ne se comporterait pas comme prévu. Mais c'est une autre histoire ... n'est-ce pas ? ;-)

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