Pointer als Parameter und Rückgabewert

Juno19

Grünschnabel
Hallo Allerseits!

Der Code sollte das Problem das ich hab verdeutlichen:

pointer.c
_______________

float* pointerRückgabe(){

float* pointer = NULL;
float array[...][...] = Werte initilisieren...
....
pointer = array;
return pointer;
}
____________________

In dieser Methode kann ich den Pointer problemlos dereferenzieren z.B. mit:

for(i=0....)
printf("%f", *(pointer+i));

Sobald ich aber der rückgabewert nutze geht die nur teilweise:

main.c
__________________
float* pointerRückgabe();

int main(){
...
float *pointerMain = NULL;
...
pointerMain = pointerRückgabe();
...
}
_____________________
dann kann ich nur eine bestimmte Anzahl von Werten(z.B bei 4 = 2 oder 14 = 5)
korrekt dereferenzieren mit:

for(i=0....)
printf("%f", *(pointerMain+i));

Das ich alle Werte korrekt erhalte funktioniert nur so, aber auch nur einmal:

printf("%f ; %f ; %f ; ..." ,*(pointerMain), *(pointerMain+1), *(pointerMain+2),....);

also sobald er einmal dereferenziert verliert er scheinbar seine Adresse.

Schlimm wird es erst wenn ich ihn dann nochmal per parameter übergeben möchte

main.c
__________________
float* pointerRückgabe();
void pointerParameter(float*);

int main(){
...
float *pointerMain = NULL;
...
pointerMain = pointerRückgabe();
pointer parameter(pointerMain);
...
}

Dann krieg ich nur ein korrekten Wert (den letzten bei einer länge Arraylänge von 14):

pointerparameter.c
__________________________

void pointerParameter(float* prm){
....
prinf("%f", *(prm+13));
}
____________________________

vielleicht ist es auch nur zufall dass dieser Wert stimmt!

Hab ich einen Denkfehler und Pointer funktkionieren nicht so?

Danke!
 
Ich hab den Verdacht, das liegt daran, dass das Array eine lokale Variable ist. Sobald du die Methode pointerZurückgeben() verlässt, wird das Array zerstört?
Wenn du das Array global deklarierst, sollte es gehen.

C++:
float arr[5][5];

float* pointerRückgabe() {
     arr[0][0] = 2;
// ...
     return &arr[0][0];
}

int main() {
     float* zeiger = pointerRückgabe();

     for (int i = 0; i < 10; i++)
          std::cout << *(zeiger+i) << std::endl;
}

Ich weiß nicht, welchen Compiler du benutzt, aber das hier geht bei mir nicht: "pointer = arr". Stattdessen muss ich "pointer = &arr[0][0]" schreiben, oder "(float*)arr".
 
Zuletzt bearbeitet:
Danke für deine Antwort!

Ich benutze MinGW als Compiler (ANSI 99 Standard). Dein Quellcode ist glaubich c++ oder?. Das ich das erste Element des Arrays auch übergeben kann war mir schon klar, hilft aber nicht.

Zu deiner Lösung:
Was nutz eine Variable Global zu definieren, wenn sie in einer anderen Datei verwendet oder an eine anderen Methoden ausserhalb der Datei weitergegeben wird.

Geht das überhaupt nicht? Dachte immer ein pointer zeigt auf einen Speicherbereich der zusammenhängt.

Bei den Aufruf: printf("%f ; %f ; ...", pointer[0] , pointer[1], ... );

Klappt es ja wunderbar! Nur eine erneute dereferenzierung scheitert!
 
Wo werden denn lokale Variablen erzeugt und abgelegt. Und was passiert, wenn man den Gültigkeitsbereich verlässt? Wird sie dann nicht zerstört? Somit würde der Zeiger ins Nirvana zeigen.
Ich weiß es nicht. Ich programmiere normalerweise nicht C++ :) .
Ich denke, wenn dein Compiler das "pointer = arr" erlaubt, dann ist das das selbe wie "pointer = &arr[0][0]". Nur Visual C++ erlaubts eben nicht :) .
 
Stimmt natürlich, dass die Variable zersört wird sobald der Gültigkeitsbereich verlassen wird, aber ich bekomme doch die referenz zurück; somit sollte der Bereich doch weiter existieren? Wie soll ich ein Array global deklarieren wenn zur laufzeit erst die Größe bestimmt wird?

Wie sollte man sonst Array in andere Dateien übergeben?
 
Zuletzt bearbeitet:
Ich habe das Gefühl, das Problem ist nicht ganz so einfach zu lösen. Folgendes geht ja auch nicht:

C++:
float **arr = new float[5][5];

error C2440: 'Initialisierung': 'float (*)[5]' kann nicht in 'float **' konvertiert werden

Hier ist ein sehr interessanter Thread zum Problem: http://forums.devarticles.com/showpost.php?p=41806&postcount=5
Insbesondere Post Nummer 5 und 6.

Ich glaub, wir müssen auf die Cracks warten... Deepthroat, wo bist du? ;)
 
Zuletzt bearbeitet:
Hi.

Juno19 hat gesagt.:
Stimmt natürlich, dass die Variable zersört wird sobald der Gültigkeitsbereich verlassen wird, aber ich bekomme doch die referenz zurück; somit sollte der Bereich doch weiter existieren?
Nein. Das Array wird auf dem Stack erstellt (nicht auf dem Freispeicher) und wenn die Funktion beendet ist und an den Aufrufer zurückgesprungen wird, dann wird der Stack aufgeräumt und der Stack selbst weiterverwendet. Da wo dann mal das Array war werden Argumente für andere Funktionsaufrufe abgelegt und damit der Inhalt des Arrays überschrieben.
Juno19 hat gesagt.:
Wie soll ich ein Array global deklarieren wenn zur laufzeit erst die Größe bestimmt wird?
Wie sollte man sonst Array in andere Dateien übergeben?
Um in C ein Array mit dynamischer Größe anzulegen existiert die calloc Funktion:
C:
#include <stdlib.h>

float* array = calloc(50, sizeof(float)); // Speicher für ein float Array der Länge 50 anlegen

... // array benutzen

free(array); // Speicher von array wieder freigeben
Gruß

PS: @Juno19: Bitte verwende für Codeschnipsel die entsprechenden Code-Tags. Danke
 
Zuletzt bearbeitet:
Du solltest dich ein wenig besser in Arrays und Pointer einarbeiten, denn ein 2D Array muss kann nur in ein PointerPointer geespeichert werden also so:
Code:
float **t_f;
float array[20][20];
t_f = array; //Wobei das das gleiche wär wie:
t_f = &array[0][0];
Deine Rückgabe MEthode gibt nur den Pointer auf &array[0] zurück, welche in ein Normalen Pointer passt.
Deswegen kannst du das auch in einem float* t_f; speichern.
Diesen kannst du dann ja ganz normal Dereferenzieren.

mfg
SGSSGene
 
Zurück