2014-06-08 7 views
20

Hier ist ein Codebeispiel durch meine Frage gefolgt:Ist diese C-Strukturzuweisungsanweisung zulässig?

#include <stdio.h> 
#include <string.h> 

struct st { 

    char stringField[100]; 
    int intField; 
}; 

typedef struct st st; 

void test(st *parameterStruct) 
{ 
    st localStruct; 
    strcpy(localStruct.stringField, "HELLO"); 
    localStruct.intField = 5; 

    *parameterStruct = localStruct; 
} 

int main() 
{ 
    st myStruct; 
    strcpy(myStruct.stringField, "XXX"); 
    myStruct.intField = 9; 

    printf("%s,%i\n", myStruct.stringField, myStruct.intField); 

    test(&myStruct); 

    printf("%s,%i\n", myStruct.stringField, myStruct.intField); 

    return 0; 
} 

OUTPUT:

XXX,9 
HELLO,5 

Ich dachte, dass da die Struktur ‚localStruct‘ wurde in einer Funktion erstellt (NICHT malloc) hatte Der lokale Bereich und damit die Speicherorte, in denen er gespeichert wurde, konnten nach der Ausführung der Funktion überschrieben werden. Ich habe jedoch versucht, dieses Beispielprogramm auszuführen, und es wurde ohne Probleme ausgeführt. Ich dachte, dass die zweite Druckanweisung Gibberish auf den Bildschirm drucken würde, da ich 'myStruct' der lokalen Variablen 'localStruct' zugewiesen hatte (im Gegensatz zu 'localStruct', das dynamisch zugewiesen wurde). Ich weiß, wenn 'localStruct' mit malloc erstellt wurde, würde es keine solchen Probleme geben.

Meine Frage: Ordnen Sie die Strukturvariable 'myStruct' (eine nicht dynamische lokale Variable) y mit einem Zeiger im Funktionstest in Ordnung und sicher zu tun? Ich hoffe, dass die Frage klar ist.

+7

Gut geschriebene Frage mit SSCCE, Sie guten Herr verdienen eine +1. –

+0

(Nur Nitpick: vielleicht kann der Titel zu etwas weniger allgemein verbessert werden?) – usr2564301

Antwort

9

Zuordnung immer kopiert.

Wenn Sie so etwas wie *x = &y tun (die Typen angepasst vorausgesetzt - wenn der Parameter als st** x erklärt wurde, zum Beispiel), würden Sie die Adresse y werden kopiert, aber da y bald den Gültigkeitsbereich verlassen, dass Zuordnung würde sei unsicher, wie du befürchtet hast.

Aber da du *x = y stattdessen tun (wo der Parameter st* x deklariert wird), Sie kopieren den Inhalt y-*x, so auch nach y den Gültigkeitsbereich verlässt, die in *x gespeicherten Daten gültig sein sollte.

+4

Ich denke du meinst 'x = & y' nicht' * x = & y'. Zumindest passt es der Frage besser IMO. Nun, außer du meinst "x" ist ein Zeiger auf einen Zeiger. – luk32

+0

@ luk32 True, aber es würde die Adresse für den äußeren Ausdruck nicht ändern, was nicht die Tatsache zeigen würde, dass der zugewiesene Ausdruck den Gültigkeitsbereich verlässt. Deshalb habe ich (unbehaglich) es mit "der Annahme, dass die Typen gültig waren" handwaved. –

+2

Ja, das stimmt für das Beispiel * nicht-funktionieren-wie erwartet * es müsste "test (st ** x)" sein. Es war ein wenig verwirrend in der 1. Form. – luk32

7

Ja. Es ist sicher.

Wenn Sie zuweisen:

*x = y; 

Die Mitglieder des y werden in die entsprechenden Mitglieder von *x kopiert. Es funktioniert so, als ob Sie ein Mitglied zum Mitglied kopiert haben.

1

C Strukturzuweisung erlauben. Zwei Strukturen können zugewiesen werden, wenn sie vom kompatiblen Typ sind. Zwei Strukturen deklariert zur gleichen Zeit sind kompatibel und Strukturen deklariert mit dem gleichen "Struktur-Tag" oder der gleiche Typ Name sind auch kompatibel.

Im Beispiel Sie zur Verfügung gestellt, die beide *x und y werden mit dem gleichen Strukturtyp Namen erklärt st, sind beide kompatibel und somit *x = y die Zuordnung ist legal. Da st x in main eine Struktur vom vollständigen Typ erzeugt, ist die Übergabe ihrer Adresse an eine Funktion zulässig. In Ihrer Funktion kopiert die Zuweisung *x = y einfach den Inhalt der lokalen Variablen y zu *x und diese Änderung zu *x wird beibehalten und in x in main widergespiegelt.

Verwandte Themen