Zugriff auf ***pointer!
-
Hallo Leute,
helft mir bitte, ich komme mit Pointer durcheinander ("Buch über Pointer wurde an die falsche Adresse geliefert")
Mein Problem in diesem Beispiel hier unten liegt in der for-Schleife mit dem strdup(). Bereits beim 2. Durchlauf gibt es Core dump...
Was mache ich falsch? Danke Euch!int nGetFunc_A (...) { char **ppcVar_A = NULL; ... nGetFunc_B (&ppcVar_A); ... return 0; } int nGetFunc_B (char ***pppcVar_B) { int i = 0; char **ppcVar_C = NULL; nGetFunc_C(ppcVar_C); *pppcVar_B = (char **) calloc (3, sizeof(char *)); ... for (i = 0; i < 3; i++) { (*pppcVar_B)[i] = strdup (ppcVar_C[i]); } ... for (i = 0; i < 3; i++) { free (ppcVar_C[i]); ppcVar_C[i] = NULL; } free (ppcVar_C); ppcVar_C = NULL; return 0; }
-
Das kann ich dir sagen: dein "varC" ist vom Typ char**, oder übersichtlicher char* varC[], also ein Array von Zeichenketten.
In deinen "funcC" kopierst du beim Aufruf die Adresse des char**, also einen Zeiger auf das erste Element des Arrays.
In deiner funC allokierst du wahrscheinlich einmal Speicher für das Array und dann für jedes Element im Array (die Zeichenkette) genügend Speicher.Das Problem: die Adresse wo das Array mit dem Zeichenketten gespeichert wird, wird nie nach "funcB" übermittelt, um den Zeiger "varC" zu manipulieren müsstest du dessen Adresse reingeben, also ein char*** oder char** pvarC[] (ein Zeiger auf ein Array von Zeichenketten).
Dann kannst du in "funC" den Parameter einmal derefenzieren und die Adresse des Arrays dort ablegen.
-
S.T.A.L.K.E.R. schrieb:
Das Problem: die Adresse wo das Array mit dem Zeichenketten gespeichert wird, wird nie nach "funcB" übermittelt, um den Zeiger "varC" zu manipulieren müsstest du dessen Adresse reingeben, also ein char*** oder char** pvarC[] (ein Zeiger auf ein Array von Zeichenketten).
Dann kannst du in "funC" den Parameter einmal derefenzieren und die Adresse des Arrays dort ablegen....ok, und so müsste es korrekter sein (Fehler von mir):
int nGetFunc_A (...) { char **ppcVar_A = NULL; ... nGetFunc_B (&ppcVar_A); ... return 0; } int nGetFunc_B (char ***pppcVar_B) { int i = 0; char **ppcVar_C = NULL; // Korrektur // nGetFunc_C(&ppcVar_C); *pppcVar_B = (char **) calloc (3, sizeof(char *)); ... for (i = 0; i < 3; i++) { (*pppcVar_B)[i] = strdup (ppcVar_C[i]); } ... for (i = 0; i < 3; i++) { free (ppcVar_C[i]); ppcVar_C[i] = NULL; } free (ppcVar_C); ppcVar_C = NULL; return 0; }
???
Danke.
-
Genau, sonst hab ich auch keinen Fehler gefunden in deiner "funcB", wenn deine "funcC" alles richtig macht, dann sollte es jetzt laufen.
-
S.T.A.L.K.E.R. schrieb:
Genau, sonst hab ich auch keinen Fehler gefunden in deiner "funcB", wenn deine "funcC" alles richtig macht, dann sollte es jetzt laufen.
Ja, eben, dachte ich mir auch. Aber hier mache ich mir Gedanken, ob es stimmt:
(*pppcVar_B)[i] = strdup (ppcVar_C[i]);
Ob diese Zuweisung an der richtigen Stelle Platz reserviert.
-
shuriko schrieb:
S.T.A.L.K.E.R. schrieb:
Genau, sonst hab ich auch keinen Fehler gefunden in deiner "funcB", wenn deine "funcC" alles richtig macht, dann sollte es jetzt laufen.
Ja, eben, dachte ich mir auch. Aber hier mache ich mir Gedanken, ob es stimmt:
(*pppcVar_B)[i] = strdup (ppcVar_C[i]);
Ob diese Zuweisung an der richtigen Stelle Platz reserviert.
Da hab ich auch zuerst den Fehler vermutet, aber das stimmt schon, du derefenzierst den Zeiger auf das Array mit dem Zeichenketten und wählst, dann den i. Eintrag aus und dort speicherst du einen Pointer auf die Zeichenkette.
-
Dank meinen Kollegen wurde der Fehler gefunden. Der Zugriff war falsch.
Korrekt wäre:
*(&(*pppcVar_B)[i]) = strdup (ppcVar_C[i]);
Jetzt bin ich durchgepointet...
-
Also das finde ich sehr seltsam, dass es damit plötzlich klappen soll.
Genaugenommen so seltsam, dass ich es selbst getestet habe, bei mir geht folgendes ohne Access Violation, Memory Leaks oder sonst etwas:#define _CRTDBG_MAP_ALLOC #include <stdio.h> #include <malloc.h> #include <string.h> #include <crtdbg.h> int main() { int i; char **str_array = NULL; char ***ptr_str_array = &str_array; char *src_str_array[] = { "Hallo", "Welt", "God" }; *ptr_str_array = (char**)calloc(3, sizeof(char *)); for( i = 0; i < 3; ++i ) { (*ptr_str_array)[ i ] = strdup( src_str_array[ i ] ); } for( i = 0; i < 3; ++i ) { char *str = str_array[ i ]; printf( "%s\n", str ); } for( i = 0; i < 3; ++i ) { free( str_array[ i ] ); } free( str_array ); _CrtDumpMemoryLeaks(); }
Mein src_str_array hab ich statisch initialisiert damit ich nicht noch deine funcC nachbauen muss, aber wenn die ordentlich arbeitet macht es ja keinen Unterschied. Sollte ich etwas nicht so haben wie in deinem Programm, dann korrigiere mich.