Malloc einen Zeiger auf einen Zeiger auf eine Struktur Array durch das Bezugs
-
08-07-2019 - |
Frage
Die folgende Code kompiliert, aber sofort stürzt aus Gründen offensichtlich andere, aber nicht für mich. Ich kann nicht scheinen, richtig zu machen, kann mir jemand sagen, wie dies zu beheben.
*array_ref[2] = array[0];
*array_ref[3] = array[1];
Es stürzt auf dem Teil jedes Mal.
typedef struct test {
char *name;
char *last_name;
} person;
int setName(person ** array, person ***array_ref) {
*array = malloc (5 * sizeof(person));
*array_ref= malloc(5 * sizeof(person*));
array[0]->name = strdup("Bob");
array[1]->name = strdup("Joseph");
array[0]->last_name = strdup("Robert");
array[1]->last_name = strdup("Clark");
*array_ref[2] = array[0];
*array_ref[3] = array[1];
return 1;
}
int main()
{
person *array;
person **array_r;
setName(&array,&array_r);
printf("First name is %s %s\n", array[0].name, array[0].last_name);
printf("Second name is %s %s\n", array_r[3]->name, array_r[3]->last_name);
while(1) {}
return 0;
}
Lösung
Operator []
hat eine höhere Priorität als einstellige operator*
. Daher folgt aus:
*array_ref[2] = array[0];
*array_ref[3] = array[1];
eigentlich bedeutet:
*(array_ref[2]) = array[0];
*(array_ref[3]) = array[1];
Typen sind richtig hier, weshalb es kompiliert. Aber aus dem Code ist es klar, dass Ihre Absicht tatsächlich war:
(*array_ref)[2] = array[0];
(*array_ref)[3] = array[1];
So verwenden nur Klammern.
Andere Tipps
Sie Platz für die array_ref Zeiger zugewiesen, aber nicht für das, was sie zeigen auf.
Versuchen Sie, die folgenden in setName Ändern ()
*array_ref[2] = array[0];
*array_ref[3] = array[1];
*(*array_ref+2) = array[0];
*(*array_ref+3) = array[1];
Das funktioniert.
array[1]->name
ist Ihr Problem. Dies sollte (*array)[1].name
. Beachten Sie, wie die beiden nicht gleichwertig sind. Alle ähnliche Anwendungen haben das gleiche Problem, mit Ausnahme von [0]
, die zufällig das Richtige tut.
Beachten Sie, dass array
, die Funktionsparameter, nicht Ihr Array, es ist ein Zeiger auf das Array.
In Funktionen wie dies Ich ziehe Code wie:
int setName(person ** out_array, person ***out_array_ref) {
person* array = malloc(5 * sizeof(person));
person** array_ref = malloc(5 * sizeof(person*));
array[0].name = strdup("Bob");
array[1].name = strdup("Joseph");
array[0].last_name = strdup("Robert");
array[1].last_name = strdup("Clark");
// I'm guessing this was your intent for array_ref, here:
array_ref[2] = &array[0];
array_ref[3] = &array[1];
*out_array = out_array;
*out_array_ref = array_ref;
return 1;
}
Beachten Sie, dass dies sowohl array[1]->name
fängt wie von Roger Pate, und *array_ref[2] = array[0]
wie (fast) bemerkt Pavel bemerkt - deren Lösung (* array_ref) [2] = array [0] weist von einer nicht zugeordneten person*
array[1]
- beide sind schwer mit dem zusätzlichen dereferenzieren zu bemerken.
Natürlich habe ich dies meistens tun, weil ich C ++ verwenden, und dies erhöht Ausnahme Sicherheit;).