49 votes

Obtenir un pointeur suspendu en retournant un pointeur d'un tableau local de style C

Je suis un peu confus par le code suivant:

#include <iostream>

const char* f()
{
    const char* arr[]={"test"};
    return arr[0];
}

int main()
{
    auto x = f();
    std::cout << x;
}

À mon avis, ce code doit être UB (comportement indéfini). Nous retourner un pointeur vers un style d'élément de tableau à l'intérieur d'une étendue locale. Les choses allaient mal. Cependant, aucun des compilateurs j'ai testé avec se plaindre (j'ai utilisé -Wall -Wextra -pedantic sur les deux g++ et clang). valgrind ne se plaint pas non plus.

Le code ci-dessus valide ou est-il UB qu'on ne le pense?

PS: en cours d'exécution, il semble produire le "bon" résultat, c'est à dire l'affichage de "test", mais ce n'est pas une indication de la décision correcte.

79voto

Barry Points 45207

Non, il n'est pas UB.

Ce:

const char* f()
{
    const char* arr[]={"test"};
    return arr[0];
}

Peut être réécrit pour l'équivalent:

const char* f()
{
    const char* arr0 = "test";
    return arr0;
}

Donc, nous sommes juste de retour d'un pointeur local, à une chaîne littérale. Les littéraux de chaîne ont statique de la durée de stockage, rien ne se balance. La fonction est vraiment la même chose que:

const char* f()
{
    return "test";
}

Si vous avez fait quelque chose comme ceci:

const char* f() {
    const char arr[] = "test"; // local array of char, not array of char const*
    return arr;
}

Maintenant, qu' est-UB - nous sommes de retour balançant un pointeur.

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