Lokale variablen - Pointer vs. Array
-
Hallo community
In der Funktion B wird der String "FGHIJ" irgendwo im speicher abgelegt und nicht auf dem Stack. Lediglich der Pointer wird auf dem Stack abgelegt.
In der Funktion A wiederum wird sowohl der Array-Pointer, wie auch der Stringwert "ABCDE" auf dem Stack abgespeichert.
Mir ist an dieser stelle unklar, wieso der String in der Funktion A auf dem Stack abgelegt wird. Müsste da nicht einfach die Adresse des Arrays abgelegt werden wo wie bei der Funktion B?
void my_function_A(char *ptr) { char a[] = "ABCDE" . . }
void my_function_B(char *ptr) { char *cp = "FGHIJ" . . }
Freundliche Grüsse
Samuel
-
Es gibt einen subtilen Unterschied zwischen char a[] = "ABCDE"; und char *cp = "FGHIJ". Ich versuche das mal zu erklaren:
In der Funktion B wird durch
char *cp = "FGHIJ"
Speicher angefordert im Heap, der String "FGHIJ" wird hineingeschrieben und dann wird ein Pointer darauf zurueckgegeben. Du hast also Speicher im Heap, der nicht automatisch geloescht wird nach dem Ende des Funktionsaufrufs.
In der Funktion A wird dir durch
char a[] = "ABCDE"
ein Array erzeugt mit einzelnen chars, das heisst der obige Code ist aequivalent zu:
char a[] = {'A', 'B', 'C', 'D', 'E'};
Und da Arrays, die auf diese Weise definiert werden, in C++ auf den Stack kommen, wird das Array nach Beendigung der Funktion automatisch geloescht.
-
in C++
@icarus2: Einfach nein! Auch wird wahrscheinlich kein Speicher auf dem Heap angefordert. Ansonsten: http://stackoverflow.com/questions/4090434/strtok-char-array-versus-char-pointer
-
icarus2 schrieb:
char a[] = "ABCDE"
ein Array erzeugt mit einzelnen chars, das heisst der obige Code ist aequivalent zu:
char a[] = {'A', 'B', 'C', 'D', 'E'};
Da fehlt noch das '\0' am Ende, da es ein Stringliteral ist.
Das Array a darfst du auch beschreiben, während der Speicher auf den cp zeigt i.A. konstant ist.
-
Sorry fuer die Fehler in meinem Post.
Hab den wohl grad ziemlich verhauen
-
icarus2 schrieb:
Es gibt einen subtilen Unterschied zwischen char a[] = "ABCDE"; und char *cp = "FGHIJ". Ich versuche das mal zu erklaren:
Ich auch:
char a[] = "ABCDE";
Hier wird ein fortlaufender Speicherplatz von strlen("ABCDE")+1 Bytes reserviert (innerhalb von {} Codeblöcken mit auto, außerhalb mit (implizit) static Speicherklasse) und das Literal "ABCDE" wird ausschließlich zur Initialisierung, d.h. Befüllen des o.g. Speicherbereiches benutzt, mit '\0' Terminierung. "ABCDE" ist hier kein eigenes Speicherobjekt, das anderweitig ansprechbar/benutzbar wäre. Es ist wenn man so will flüchtig.char cp = "FGHIJ";
Reserviert einen fortlaufenden Speicherbereich von sizeof(char) Bytes (innerhalb von {} Codeblöcken mit auto, außerhalb mit (implizit) static Speicherklasse) und initialisiert diesen mit der Adresse eines weiteren Speicherbereiches irgendwo anders, in dem strlen("FGHIJ")+1 Bytes reserviert und entsprechend befüllt wurden (wie im oberen Fall).
"FGHIJ" ist hierbei weiterhin über cp verwendbar, wenn cp mal geändert würde, wäre aber auch hier "FGHIJ" nicht mehr nutzbar, aber weiterhin vorhanden (irgendwo im Prozessspeicher), im Gegensatz zu oben.DirkB schrieb:
Das Array a darfst du auch beschreiben, während der Speicher auf den cp zeigt i.A. konstant ist.
Genauer wäre hier zu sagen, dass bei
*char cp = "FGHIJ";
das Stringliteral selber nicht konstant ist (const char *cp) sondern lediglich standardisiert ist, dass der schreibende Zugriff auf Elemente dieses Literalarrays zu undefiniertem Verhalten führt.
Zu erwähnen wäre noch, dass im Gegensatz zu C bei C++ hier const char *cp spezifiziert ist (ein Stringliteral ist hier also tatsächlich konstant per Definition),
alsochar *cp="FGHIJ";
durchaus möglich wäre, in C++ hingegen nicht mehr standardkonform wäre und
const char *cp="FGHIJ";
heißen müsste.
Nichtsdestotrotz ist es auch in C in gut gewarteten Quelltexte üblich, ein const als Compilerhinweis zu spendieren, falls sich der Zeiger nicht mehr ändert und anderweitig wiederverwendet wird, also ein "spendiertes" const würde beichar *p=0; char a[]="ABCDE"; char *cp="FGHIJ"; ... cp=a; ... p=cp;
natürlich scheitern.