Speicher in Funktion allokieren und außerhalb der Funktion nutzen
-
Seas!
Es geht im Kern um folgendes: Ich möchste innerhalb einer Funktion Speicher reservieren und mit Daten füllen. Der Speicher und die Daten sollen nach Beendigung der Funktion auch noch vorhanden sein.
Das Beispiel unten muss ich, glaube ich, nicht erklären, da die meisten hier Profis sind.
Das Problem ist, dass das Programm jedes mal abschmiert. Nur sehe ich den Fehler nicht.
#include <stdio.h> #include <stdlib.h> int square_array(int** input,int* n, int** output); int main() { int i,n=10; int* input=malloc(n*sizeof(input)); if (input==NULL) return -1; int* output; for(i=0; i<n; i++)input[i]=i; square_array(&input,&n,&output); for(i=0; i<n; i++)printf("output[i]=%d\t",output[i]); return 0; } int square_array(int** input, int* n ,int** output) { *output = malloc((*n)*sizeof(output)); if (output==NULL) return -1; int i; for(i=0; i<*n; i++) { (*output)[i]=(*input[i])*(*input[i]); } return 0; }
Weiß jemand Rat? Ich bin für Erklärungen und dergleichen immer dankbar!
LG Felix
-
(*output)[i] ist etwas anderes als (*output[i])
Noch was:
output ist der Doppelzeiger. ALso ergibt sizeof(output) auch nur die Groöße vom Zeiger und nicht von **output (dem int)Zeile 26 kommt etwas spät, denn wenn output an der Stelle NULL ist, dann hast du in Zeile 25 schon an die Stelle NULL geschrieben.
Damit überprüfst du nicht das malloc, sondern ob du Funktion vernünftige Parameter erhalten hat.
-
Ah, ich habs gemerkt.
Ich bin die Pointergeschichten nochma händisch mit Papier und Stift durchgegangen und hab (vermute ich) die grundsätzlichen Fehler gefunden (man muss sich einfach immer vor Augen halten, das in Funktionen mit Kopien gearbeitet wird). Der korrigierte Code soweit:#include <stdio.h> #include <stdlib.h> int square_array(int** input,int* n, int*** output); int main() { int i,n=10; int* input; input = malloc(n*sizeof(*input)); if (input==NULL) return -1; int** output; for(i=0; i<n; i++)input[i]=i; square_array(&input,&n,&output); for(i=0; i<n; i++)printf("%d ",input[i]); printf("\n"); for(i=0; i<n; i++)printf("%d ",(*output)[i]); printf("\n"); return 0; } int square_array(int** input, int* n ,int*** output) { int i, *buffer; buffer=malloc((*n)*sizeof(*buffer)); *output=&buffer; if(*output==NULL)return -1; for(i=0; i<*n; i++)(**output)[i]=(*input)[i]*(*input)[i]; return 0; }
Das Problem ist nun noch, dass er den allokierten Speicher nach Beendigung der Funktion vergisst. Die Frage ist: kann man das verhindern, ohne das mit einer globalen Variable oder einer Variable in der Aufrufenden Funktion zu erschlagen? Mein Problem ist: Was, wenn ich nicht von vornherein weiß, wieviel Speicher ich allokieren muss? Wenn ich das in der Funktion herausfinde und mich das außerhalb eventuell garnicht interessiert?
LG Felix
-
kellerfe schrieb:
Ah, ich habs gemerkt.
Ich bin die Pointergeschichten nochma händisch mit Papier und Stift durchgegangen und hab (vermute ich) die grundsätzlichen Fehler gefundenDas bezweifle ich. Das Unverständnis über Zeiger lässt sich nicht dadurch lösen, indem man überall, wo einem etwas unklar ist, ein '*' einträgt.
kellerfe schrieb:
Wenn ich das in der Funktion herausfinde und mich das außerhalb eventuell garnicht interessiert?
Indem du diese Variable nur in der Funktion selbst verwendest und nicht nach draußen gibst.
-
Dann bin ich mal so frei, und räume die Zweifel aus (sowas lasse ich ungern auf mir sitzen, nix für ungut):
square_array() bekommt als Argumente:
- einen Zeiger auf einen Zeiger. Würde auch nur mit einem Zeiger funktionieren, weil dieser Zeiger nicht verändert wird.
- einen Zeiger auf int. Würde ebenfalls ohne Zeiger funktionieren, weil auch hier nichts geändert wird.
- einen Zeiger auf einen Zeiger auf einen Zeiger. Hier mache ich das, weil ich ich den Zeiger aus der Main (*output) umbiegen möchte auf einen anderen Zeiger. Würde ich nur einen Zeiger auf einen Zeiger verwenden, würde eine Kopie des Zeigers aus der Main angelegt, dieser umgebogen und die Umleitung fände nur in der Funktion, aber nicht in der Main statt.Indem du diese Variable nur in der Funktion selbst verwendest und nicht nach draußen gibst.
Ich will die Variable und deren Speicher natürlich nutzen. Deshalb ganz grundsätzlich: Kann ich innerhalb einer Funktion Speicher reservieren und der aufrufenden Funktion diesen zur Verfügung stellen?
EDIT: Mea culpa, Wutz hatte natürlich recht, es ginge grundsätzlich auch anders und mein Ansatz ist ein Zeiger-Overkill. Mein Ansatz ohne dies wäre:
int square_array(int* input,int n, int** output); int main() { int i,n=10; int* input = malloc(n*sizeof(*input)); if (input==NULL) return -1; int* output; for(i=0; i<n; i++)input[i]=i; square_array(input,n,&output); for(i=0; i<n; i++)printf("%d ",input[i]); printf("\n"); for(i=0; i<n; i++)printf("%d ",output[i]); printf("\n"); return 0; } int square_array(int* input, int n ,int** output) { int i, *buffer = malloc(n*sizeof(*buffer)); *output=buffer; if(*output==NULL)return -1; for(i=0; i<n; i++)(*output)[i]=input[i]*input[i]; return 0; }
Ist eigentlich einfach zu merken: Will man einen Wert ändern und außerhalb einer Funktion nutzen, ohne return zu verwenden, ist ein Pointer auf diesen Wert hilfreich.
Dennoch bleibt meine grundsätzliche Frage bestehen. Diese Version funktioniert zwar, aber die Frage ist: Ist der SPeicher, welchen ich in square_array allokiert habe, auch außerhalb davon gültig (besonders in der Main)?