Supprimer et pointeur invalide

int main() { char* a=new char[20]; cin>>a; cout<<" character at 7-th position."<<a[6]; delete a+4; cout<<a[0]; return 0; } 

Consortingbution:

 1234567894567 

Sortie:

 character at 7-th position.6 *** glibc detected *** ./test free() invalid pointer:.... 

Maintenant j’ai 3 questions

  1. Est-il exact que delete a+4 ne supprime le caractère que d’ a+4 ?
  2. Si la réponse à la question précédente est oui, que se passe-t-il avec a[0] Nous devrions obtenir le résultat.
  3. pour supprimer un bloc de mémoire, nous devons écrire delete[] .Mais dans ce cas, comment se fait-il que tous les éléments soient supprimés?

Il n’y a que trois types de valeurs de pointeur que vous pouvez transmettre en tant qu’opérande de delete :

  1. Valeur de pointeur nulle. Ils sont simplement ignorés.
  2. Un object scalaire complet (pas un tableau) précédemment alloué avec new , soit:
    • Le pointeur exact renvoyé par new
    • Un pointeur sur un sous-object de base du pointeur renvoyé par new , si et seulement si le type du sous-object de base a un destructeur virtual

Aucune de ces valeurs de pointeur ne doit JAMAIS être transmise à la delete scalaire:

  1. Le résultat du tableau new ou new[] (utilisez delete[] place)
  2. Le résultat de malloc ou de tout autre allocateur qui n’est pas new
  3. Adresse d’un object avec durée de stockage automatique ou statique
  4. L’adresse d’un membre ou d’un élément de tableau membre
  5. Valeurs de pointeur non initialisées
  6. Pointeurs sur des objects déjà supprimés

Si vous enfreignez cette règle, vous obtenez un comportement indéfini . Cela signifie que votre programme risque de planter avec un message indiquant qu’une suppression non valide a été détectée. Ou bien vos données peuvent être corrompues, enregistrées dans vos fichiers de données, envoyées à votre patron, montrées au client, et plus tard, vous êtes viré. Alors n’enfreignez pas la règle.

Votre code tombe dans la catégorie “NE FAITES JAMAIS CELA # 4”.


Cela fonctionne parce qu’une implémentation peut (et la plupart le font) suivre des informations supplémentaires appelées métadonnées avec chaque bloc alloué. Par exemple, la taille du bloc, ce qui est très important pour permettre la réutilisation. Il n’y a pas de métadonnées pour une partie d’un bloc et il peut ne pas y avoir aucun moyen de trouver les métadonnées à partir d’un pointeur situé au milieu.

  1. Non, delete est le contraire de new . Vous supprimez essentiellement le même pointeur que vous obtenez lors de l’allocation. La suppression d’autres pointeurs n’est pas définie, d’où l’erreur “pointeur non valide”. Si vous avez alloué un tableau, vous devez utiliser delete[] . En ce moment, vous perdez (“ne libérez pas”) cette mémoire. Donc utilisez delete [] a; après que vous avez terminé.

  2. Pas vraiment applicable.

  3. Parce que c’est comme ça que C ++ fonctionne. C’est l’opération que vous utilisez pour libérer un tableau que vous avez alloué.

Il semble que vous souhaitiez supprimer un caractère d’une chaîne, puis imprimer la chaîne. Si c’est ce que vous recherchez, envisagez d’utiliser un std::ssortingng et d’utiliser sa fonction remove member. Quoi qu’il en soit, a[0] est un caractère, pas un caractère char* , ce dernier étant une chaîne de style C. Vous devriez

 cout << a; 

au lieu.