c++ - übergeben - Einen freien Zeiger erhalten, indem ein Zeiger von einem lokalen C-artigen Array zurückgegeben wird




this c++ deutsch (2)

Ich bin ein wenig verwirrt durch den folgenden Code:

#include <iostream>

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

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

Meiner Meinung nach sollte dieser Code UB sein (undefiniertes Verhalten). Wir geben einen Zeiger auf ein Array-Element im C-Stil innerhalb eines lokalen Bereichs zurück. Die Dinge sollten schief gehen. Keiner der Compiler, die ich getestet habe, beschweren sich jedoch (ich habe -Wall -Wextra -pedantic sowohl auf g ++ als auch auf clang verwendet). valgrind beschweren sich auch nicht.

Ist der obige Code gültig oder ist er UB, wie man meinen könnte?

PS: läuft es scheint das "richtige" Ergebnis zu erzeugen, dh Anzeige "Test", aber das ist kein Hinweis auf die Richtigkeit.


Das Array arr hat eine lokale Speicherdauer und verschwindet am Ende des Bereichs. Das String-Literal "test" jedoch ein Zeiger auf einen statischen Speicherort. Das vorübergehende Speichern dieses Zeigers im lokalen Array arr vor dem Zurückgeben ändert diesen Wert nicht. Es wird immer ein statischer Speicherort sein.

Beachten Sie, dass die zusätzliche Konvertierung / Buchhaltung wahrscheinlich zu einem auf die Lebensdauer beschränkten Wert gemäß den temporären C ++ - Regeln führen würde, wenn die Funktion einen C ++ - Stil-Stringtyp anstelle eines C-Stils const char * würde.


Nein, es ist nicht UB.

Dies:

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

Kann in das Äquivalent umgeschrieben werden:

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

Wir geben also nur einen lokalen Zeiger an ein String-Literal zurück. String-Literale haben statische Speicherdauer , nichts baumelt. Die Funktion ist wirklich die gleiche wie:

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

Wenn Sie so etwas getan haben:

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

Nun , das ist UB - wir geben einen baumelnden Zeiger zurück.





undefined-behavior