web-dev-qa-db-fra.com

Qu'est-ce qu'un pointeur suspendu?

Je sais que c'est une question assez courante, mais encore nouvelle pour moi!

Je ne comprends pas le concept de pointeur suspendu, je faisais des recherches sur Google et j'écrivais des méthodes de test pour en trouver un.

Je me demande simplement s'il s'agit d'un pointeur suspendu? Comme tout exemple que j'ai trouvé retournait quelque chose, ici j'essaye quelque chose de similaire!

Merci!

void foo(const std::string name)
{
    // will it be Dangling pointer?!, with comments/Answer
    // it could be if in new_foo, I store name into Global.
    // Why?! And what is safe then?
    new_foo(name.c_str());
}

void new_foo(const char* name)
{
    // print name or do something with name...   
}
41
code muncher

Un pointeur suspendu est un pointeur qui pointe vers des données non valides ou vers des données qui ne sont plus valides, par exemple:

Class *object = new Class();
Class *object2 = object;

delete object;
object = nullptr;
// now object2 points to something which is not valid anymore

Cela peut se produire même dans les objets alloués par pile:

Object *method() {
  Object object;
  return &object;
}

Object *object2 = method();
// object2 points to an object which has been removed from stack after exiting the function

Le pointeur renvoyé par c_str peut devenir invalide si la chaîne est modifiée par la suite ou détruite. Dans votre exemple, vous ne semblez pas le modifier, mais comme vous ne savez pas exactement ce que vous allez faire avec const char *name il est impossible de savoir que votre code est intrinsèquement sûr ou non.

Par exemple, si vous stockez le pointeur quelque part et que la chaîne correspondante est détruite, le pointeur devient invalide. Si tu utilises const char *name juste dans le cadre de new_foo (par exemple, à des fins d'impression), le pointeur restera valide.

53
Jack

Un pointeur suspendu est un pointeur (non NULL) qui pointe vers une zone mémoire non allouée (déjà libérée).

L'exemple ci-dessus doit être correct étant donné que la chaîne n'est pas modifiée via new_foo.

10
Miklós Homolya

Pour une question de style, j'explique un pointeur pendant comme "un pointeur qui existe toujours, même si l'objet qu'il désignait n'existe plus".

Dans votre cas, le pointeur name existe pour une période plus courte que l'objet vers lequel il pointe. Donc ça ne pend jamais.

À l'intérieur des classes C++ courantes, les pointeurs se balancent pendant une très courte période, à l'intérieur des destructeurs. En effet, l'instruction delete est antérieure à la dernière } du destructeur, tandis que le pointeur lui-même cesse d'exister au dernier }. Si vous ne voulez pas vous en soucier, utilisez par exemple unique_ptr<T>. Le T* le pointeur va pendant très peu de temps à l'intérieur du unique_ptr::~unique_ptr destructeur, qui est parfaitement sûr.

4
MSalters

Tiré de ici . Même si c'est pour C, c'est la même chose pour C++.

Pointeur suspendu

Si un pointeur pointe vers l'adresse mémoire d'une variable mais après qu'une certaine variable a été supprimée de cet emplacement mémoire alors que le pointeur pointe toujours vers cet emplacement mémoire. Un tel pointeur est connu sous le nom de pointeur suspendu et ce problème est connu sous le nom de problème de pointeur suspendu.

Initialement

enter image description here

Plus tard

enter image description here

Exemple

#include<stdio.h>

int *call();
int main() {

  int *ptr;
  ptr = call();

  fflush(stdin);
  printf("%d", *ptr);
  return 0;
}

int * call() {
  int x=25;
  ++x;

  return &x;
}

Sa sortie sera une ordure car la variable x est une variable locale. Sa portée et sa durée de vie se trouvent dans l'appel de fonction, donc après avoir renvoyé l'adresse de la variable x, x est devenu mort et le pointeur pointe toujours ptr pointe toujours sur cet emplacement.

4
Ashish Ahuja