2017-01-23 8 views
2

Unten ist die Darstellung für Person,Zuordnung (const char *) Zeigertyp - Segmentation fault

typedef struct{ 

    const char *firstName; 
    const char *lastName; 
}PersonDetails; 

typedef struct{ 

    const long *sinKey; 
    PersonDetails *value; 
}Person; 

wo bevölkern die firstName Mitglied Segmentierungsfehler erzeugt,

int main(void){ 
    .... 
    Person *person = malloc(sizeof(Person)); 
    const long key1 = 364222888L; 
    printf("Before key assignment\n"); 
    person->sinKey = &key1; 
    printf("Before first name assignment\n"); 
    person->value->firstName = "Sham"; 
    printf("Before last name assignment\n"); 
    person->value->lastName = "S"; 
    .... 
} 

const char *firstName enthält eine unveränderliche Zeichenfolge. Diese unveränderliche Zeichenfolge wird im Abschnitt .rodata gespeichert. firstname kann den Zeigepunkt ändern.


Aber unten ist die Ausgabe,

$ ./pq.exe 
... 
Before key assignment 
Before first name assignment 
Segmentation fault (core dumped) 

Wie dieses Problem zu lösen?

+1

'Wert' ist nicht zugeordnet ... – LPs

Antwort

10

Wenn Sie das tun

Person *person = malloc(sizeof(Person)); 

Sie nur Speicher für die person Struktur zuordnen. Sie reservieren keinen Speicher für person->value. Sie nicht einmal initialisierenperson->value so wird sein Wert unbestimmt, was zu undefined Verhalten, wenn Sie es dereferenzieren.

Meine Empfehlung ist nicht Verwenden Sie einen Zeiger für person->value, nur eine einfache Struktur (Nicht-Zeiger) -Instanz.


auf einer nicht verwandte Notiz, mit diesem Zeiger person->sinKey, besonders vorsichtig sein, wenn Sie in Ihrem aktuellen Code, um die Struktur in einer anderen Funktion erstellen. Die von Ihnen vorgenommene Zuweisung führt dazu, dass person->sinKey auf die lokale Variable zeigt, die nach der Rückkehr der Funktion den Gültigkeitsbereich verlässt.

Es funktioniert, wenn Sie die Struktur in der main Funktion erstellen, da dann die Lebensdauer der Variablen, die Sie person->sinKey Punkt machen, die Lebensdauer des Programms sein wird.

Dies, zusammen mit dem oben genannten Problem, führt mich zu der Frage, warum Sie Zeiger so oft verwenden? Zeiger sind der Hauptgrund für Probleme im Code, besonders für (relative) Anfänger.

+0

Meinst du,' PersonDetails value' Mitglied? wo 'PersonDetails' wie oben gezeigt? – overexchange

+0

@overxchange Ja genau. –

+0

Falsch. Es gibt keinen Mehrwert durch die Pflege von '* sinKey' – overexchange

2

Sie müssen Zuordnung hinzufügen, für value Mitglied

person->value = malloc (sizeof(PersonDetails)); 

Und Sie müssen malloc Rückgabewerte überprüfen, immer

if (person->value != NULL) 
{ 
    // YOUR STUFF 
} 
2

dieses:

Person *person = malloc(sizeof(Person)); 

nicht ausreichend ist.

Sie müssen Speicher für Person-> Wert auch zuweisen.

Person *person = malloc(sizeof(Person)); 
person->value = malloc(sizeof(PersonDetails)); 
0

Wenn Sie sich entscheiden PersonDetails *value zu verwenden, müssen Sie etwas Platz dafür mit malloc() zuzuteilen. Sonst ist es nur ein fliegender Zeiger, der nirgendwohin zeigt.

Als @Some Programmierer dude vorgeschlagen, können Sie einfach PersonDetails value verwenden, und dann brauchen Sie keine Zuordnung, da es nicht mehr ein Zeiger ist.

Wenn Sie sich entscheiden, diesen Ansatz zu verwenden, würde der Code dann wie folgt aussehen:

#include <stdio.h> 
#include <stdlib.h> 

typedef struct{ 
    const char *firstName; 
    const char *lastName; 
}PersonDetails; 

typedef struct{ 
    const long *sinKey; 
    PersonDetails value; 
}Person; 


int main(void) { 
    Person *person = malloc(sizeof(Person)); 
    const long key1 = 364222888L; 

    person->sinKey = &key1; 
    printf("%ld\n", *(person->sinKey)); 

    person->value.firstName = "Bob"; 
    printf("%s\n", person->value.firstName); 

    person->value.lastName = "Smith"; 
    printf("%s\n", person->value.lastName); 

    return 0; 
} 

Ich bin immer noch nicht sicher, warum Sie const long *sinKey; verwenden? Muss das wirklich ein Zeiger sein?