"Lebenszeit" von String-Literal in C
Wäre das nicht der Zeiger zurückgegeben, indem die folgende Funktion unzugänglich?
char *foo( int rc )
{
switch (rc)
{
case 1: return("one");
case 2: return("two");
default: return("whatever");
}
}
Also die Lebensdauer einer lokalen Variablen in C/C++ ist praktisch nur innerhalb der Funktion, richtig? Das heißt, nach char* foo(int)
beendet wird, werden die Zeiger gibt es nicht mehr etwas bedeutet?
Ich bin ein wenig verwirrt über die Lebensdauer von lokalen var.
Könnte mir jemand eine gute Aufklärung?
InformationsquelleAutor der Frage user113454 | 2012-04-02
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ja, die Lebensdauer einer lokalen Variablen ist innerhalb des Bereichs (
{
,}
), in dem es erstellt wurde.Lokale Variablen haben automatische oder lokalen Speicher.
Automatischeweil Sie werden automatisch zerstört, wenn der Bereich, innerhalb dem Sie erstellt wurden, beendet.
Jedoch, Was Sie hier haben, ist ein string-literal, dem zugeordnet wird, die in einer Implementierung definiert nur-lese-Speicher. String-Literale unterscheiden sich von lokalen Variablen und Sie am Leben bleiben während des Programms Leben.Sie haben statische Dauer [Ref 1] Lebensdauer.
Ein Wort der Vorsicht!
Beachten Sie jedoch, dass jeder Versuch, zu ändern, den Inhalt einer string-literal ist ein nicht definiertes Verhalten.
User-Programme sind nicht gestattet, ändern Sie den Inhalt von einem string-literal.
Daher ist es immer aufgefordert, eine
const
während der Deklaration ein string-literal.statt,
In der Tat, in C++ ist es veraltet zu deklarieren Sie eine string-literal ohne die
const
aber nicht in c sind. Allerdings deklarieren Sie ein string-literal mit einemconst
gibt Sie den Vorteil, dass Compiler würde in der Regel geben Sie eine Warnung im Fall Sie versuchen, ändern Sie den string-literal im zweiten Fall.Beispielprogramm:
Ausgabe:
Ankündigung der compiler warnt, für den zweiten Fall aber nicht zum ersten.
EDIT: eine Antwort Auf die F gefragt von ein paar Usern hier:
Was ist der deal mit Integrale Literale?
In anderen Worten ist dieser code gültig:
Die Antwort ist, Nein dieser code ist nicht gültig, es ist schlecht ausgebildet ist & wird ein compiler-Fehler.
So etwas wie:
String-Literale sind l-Werte, ich.e: Sie können die Adresse eines string-literal, aber nicht ändern Sie den Inhalt.
Aber alle anderen Literale(
int
,float
,char
etc) sind r-Werte(c-standard verwendet den Begriff der Wert eines Ausdrucks für diese) & deren Adresse kann nicht entnommen werden alle.[Ref 1]C99-standard 6.4.5/5 "String-Literale - Semantik":
InformationsquelleAutor der Antwort Alok Save
Es ist gültig, string-Literale haben static storage duration, also der Zeiger ist nicht freistehend.
Für C, der beauftragt ist, im Abschnitt 6.4.5, Absatz 6:
Und für C++ in Abschnitt 2.14.5, Absätze 8-11:
InformationsquelleAutor der Antwort Daniel Fischer
String-Literale sind gültig für das ganze Programm (und sind nicht zugeordnet, nicht den stack), so wird es gültig sein.
Auch string-Literale sind read-only, also (guter Stil) vielleicht sollten Sie ändern
foo
zuconst char *foo(int)
InformationsquelleAutor der Antwort asaelr
Gute Frage. Im Allgemeinen, Sie haben Recht, aber dein Beispiel ist eine Ausnahme. Der compiler statisch allokiert globalen Speicher für einen string-literal. Daher wird die Adresse zurückgegeben, die von Ihrer Funktion gültig ist.
Dass dem so ist, ist eine ziemlich praktische Funktion von C, ist es nicht? Es ermöglicht eine Funktion, um wieder eine zusammengesetzte Nachricht, ohne dass der Programmierer Gedanken über den Speicher, in dem die Nachricht gespeichert ist.
Siehe auch @asaelr die richtige Beobachtung re
const
.InformationsquelleAutor der Antwort thb
Ja, es ist gültig, code, Fall 1 unten. Sie können sicher zurückkehren, C-strings, der aus einer Funktion in mindestens diesen Arten:
const char*
zu einem string-literal. Nicht geändert werden können, müssen nicht freigegeben werden, um Anrufer. Selten nützlich für die Zwecke der Rückgabe ein Standardwert, da die Befreiung problem unten beschrieben. Könnte Sinn machen, wenn Sie tatsächlich übergeben zu müssen, eine Funktion Zeiger irgendwo, so benötigst du eine Funktion zurückgeben einer Zeichenfolge..char*
oderconst char*
zu static char buffer. Muss nicht freigegeben werden vom Anrufer. Geändert werden können (entweder durch Anrufer, wenn nicht const, oder durch die Funktion zurückkehrt), sondern eine Funktion zurückgeben kann dies nicht (leicht) mehrere Puffer, also nicht (leicht) thread-sicher, und der Anrufer muss eine Kopie der zurückgegebene Wert vor dem Aufruf der Funktion wieder.char*
um eine zugewiesene Puffer mitmalloc
. Kann geändert werden, sondern muss in der Regel ausdrücklich befreit vom Anrufer, und hat die heap overhead.strdup
ist von diesem Typ.const char*
oderchar*
auf einen Puffer, der übergeben wurde, als argument an die Funktion (zurückgegebene Zeiger muss nicht auf das erste element des argument-Puffer). Lässt Verantwortung von Puffer - /Speicher-management, um die Anrufer. Viele standard-string-Funktionen sind von diesem Typ.Ein problem ist, mischen Sie diese in einer Funktion kann kompliziert werden. Aufrufer muss wissen, wie Sie es behandeln soll, der zurückgegebene Zeiger, wie lange es gültig ist, und wenn der Anrufer sollte kostenlos, und es gibt keine (schöne) Möglichkeit der Bestimmung, dass zur Laufzeit. So können Sie nicht zum Beispiel mit einer Funktion, die manchmal wird ein Zeiger auf eine heap-allokierten Puffer, der Aufrufer muss
free
und manchmal ist ein Zeiger auf einen Standard-Wert aus string-literalen, die Anrufer müssen nichtfree
.InformationsquelleAutor der Antwort hyde
Lokale Variablen gelten nur in dem Umfang, Sie sind deklariert, aber Sie deklarieren Sie nicht von lokalen Variablen in dieser Funktion.
Es ist vollkommen gültig, um zurück einen Zeiger auf ein string-literal von einer Funktion als string-literal existiert während der gesamten Ausführung des Programms, genauso wie ein
static
oder eine Globale variable würde.Wenn Sie sich Gedanken darüber, was Sie tun können ungültig sein, nicht definiert, Sie soll sich Ihre compiler-Warnungen zu sehen, wenn es ist in der Tat alles, was du falsch machst.
InformationsquelleAutor der Antwort AusCBloke
str nie dangling pointer.
Because it points to static address
wo string-Literale befindet .Es wird meist
readonly
undglobal
auf dem Programm, wenn es geladen wird .Auch wenn Sie versuchen, Sie zu befreien oder zu ändern ,wird es werfen
segmentation fault
auf Plattformen mit Speicherschutz .InformationsquelleAutor der Antwort qwr
Wird eine lokale variable auf dem Stapel reserviert. Nachdem die Funktion beendet ist, wird die variable geht out of scope und ist nicht mehr zugänglich im code. Allerdings, wenn Sie eine Globale (oder einfach - noch nicht out-of-scope) Zeiger, der Sie zugeordnet, so dass diese variable, wird es zeigen Sie auf die Stelle im stack, wo diese variable wurde. Es konnte ein Wert von einer anderen Funktion oder einen sinnlosen Wert.
InformationsquelleAutor der Antwort Imp
Im obigen Beispiel gezeigt, indem Sie, Sie sind tatsächlich wieder die zugeordneten Zeiger zu, was auch immer Funktion, die Anrufe der oben genannten. So würde Es nicht zu einer lokalen Zeiger. Und außerdem die Zeiger, die erforderlich sind, zurückgegeben werden, wird Speicher reserviert in der globalen segment.
Danken Ihnen,
Viharri P L V.
InformationsquelleAutor der Antwort VIHARRI PLV