Seite 3 von 3

Verfasst: 27.09.2008 19:27
von STARGÅTE
es geht ja nicht ums ende , sondern um die benutzung dieser Variante in einem Code. :|

es reicht ja nicht ein FreeMemory(*Test), sonder er muss es immer machen bevor er den "alten" Pointer überschreibt, um ihn nicht zu verlieren.
:wink:

Verfasst: 27.09.2008 19:34
von cxAlex
Ich mach das schon absichtlich so... die paar Bytes kann der Arbeitsspeicher schon verschmerzen... :mrgreen:

Wenn ich das nur mit Pointern mache ohne CopyMemory() zeigt der Pointer ja nur auf die Adresse der Variable in der Procedure. Wenn ich nun die funktion ein 2. mal aufrufe und sich die Werte der Variable ändern zeigen alle früheren Ergebnisse immer noch auf diesen Speicher und alle früheren Erg. ändern sich auch:

Code: Alles auswählen

Structure MyStruct


  Val1.l
  Val2.l
  Val3.d
  Val4.d
EndStructure


Procedure Return4Values(x)
  tVar.MyStruct
  tVar\Val1 = 1233*2
  tVar\Val2 = 124124*2
  tVar\Val3 = 1212.213123*2
  tVar\Val4 = 1233.123321*2
  ProcedureReturn @tVar
EndProcedure

*Test.MyStruct = Return4Values(2)

Debug *Test\Val1
Debug *Test\Val2
Debug *Test\Val3
Debug *Test\Val4

*Test3.MyStruct = Return4Values(3)

Debug *Test3\Val1
Debug *Test3\Val2
Debug *Test3\Val3
Debug *Test3\Val4

Debug *Test\Val1
Debug *Test\Val2
Debug *Test\Val3
Debug *Test\Val4
Wenn ich das ganze in einer Schleife mache gebe ich sowiso immer den alten Speicher vorher frei, das muss man dann halt manuel machen.

Verfasst: 27.09.2008 19:35
von DarkDragon
STARGÅTE hat geschrieben:es geht ja nicht ums ende , sondern um die benutzung dieser Variante in einem Code. :|

es reicht ja nicht ein FreeMemory(*Test), sonder er muss es immer machen bevor er den "alten" Pointer überschreibt, um ihn nicht zu verlieren.
:wink:
Ja eben... aber hier ist ja kein alter Pointer, hier ist nur einer. Es steht ja auch nicht im Anfänger-Forum sondern in "Code, Tipps und Tricks".

Verfasst: 27.09.2008 19:40
von cxAlex
So hier eine ERLAUBTE ( :lol: :lol: ) Version meines Codes:

Code: Alles auswählen

Structure MyStruct
  Val1.l
  Val2.l
  Val3.d
  Val4.d
EndStructure

Macro ReturnStruct(_Var, _Struct)
  *tMem = AllocateMemory(SizeOf(_Struct))
  CopyMemory(@_Var, *tMem, SizeOf(_Struct))
  ProcedureReturn *tMem
EndMacro

Macro GetStructValue(_Function,_Var,_Struct)
  *tMem = _Function
  CopyMemory(*tMem, @_Var, SizeOf(_Struct))
  FreeMemory(*tMem)
EndMacro


Procedure Return4Values()
  tVar.MyStruct
  tVar\Val1 = 1233
  tVar\Val2 = 124124
  tVar\Val3 = 1212.213123
  tVar\Val4 = 1233.123321
  ReturnStruct(tVar, MyStruct)
EndProcedure

GetStructValue(Return4Values(),Test.MyStruct,MyStruct)

Debug Test\Val1
Debug Test\Val2
Debug Test\Val3
Debug Test\Val4
Jetzt wird der alte Speicher immer Freigegeben.

Verfasst: 27.09.2008 19:47
von ts-soft

Code: Alles auswählen

Structure MyStruct
  Val1.l
  Val2.l
  Val3.d
  Val4.d
EndStructure


Procedure Return4Values(x)
  Static tVar.MyStruct
  tVar\Val1 = 1233*x
  tVar\Val2 = 124124*x
  tVar\Val3 = 1212.213123*x
  tVar\Val4 = 1233.123321*x
  ProcedureReturn @tVar
EndProcedure

Define *Test.MyStruct = Return4Values(2)

Debug *Test\Val1
Debug *Test\Val2
Debug *Test\Val3
Debug *Test\Val4
reicht das nicht?

Verfasst: 27.09.2008 20:00
von DarkDragon
ts-soft hat geschrieben:

Code: Alles auswählen

Structure MyStruct
  Val1.l
  Val2.l
  Val3.d
  Val4.d
EndStructure


Procedure Return4Values(x)
  Static tVar.MyStruct
  tVar\Val1 = 1233*x
  tVar\Val2 = 124124*x
  tVar\Val3 = 1212.213123*x
  tVar\Val4 = 1233.123321*x
  ProcedureReturn @tVar
EndProcedure

Define *Test.MyStruct = Return4Values(2)

Debug *Test\Val1
Debug *Test\Val2
Debug *Test\Val3
Debug *Test\Val4
reicht das nicht?
Wenn sich da jetzt nichts in PureBasic in den nächsten 10 Versionen ändert reicht das. Aber du weißt nie ob Static Variablen plötzlich anders ausgelagert werden.

Verfasst: 27.09.2008 20:01
von cxAlex
So verlierst du aber die alten Werte:

Code: Alles auswählen

Structure MyStruct
  Val1.l
  Val2.l
  Val3.d
  Val4.d
EndStructure


Procedure Return4Values(x)
  Static tVar.MyStruct
  tVar\Val1 = 1233*x
  tVar\Val2 = 124124*x
  tVar\Val3 = 1212.213123*x
  tVar\Val4 = 1233.123321*x
  ProcedureReturn @tVar
EndProcedure

Define *Test.MyStruct = Return4Values(2)

Debug *Test\Val1
Debug *Test\Val2
Debug *Test\Val3
Debug *Test\Val4

Define *Test2.MyStruct = Return4Values(3)

Debug *Test2\Val1
Debug *Test2\Val2
Debug *Test2\Val3
Debug *Test2\Val4

Debug *Test\Val1
Debug *Test\Val2
Debug *Test\Val3
Debug *Test\Val4
Weil alle Werte auf den selben Speicher zeigen.

Verfasst: 27.09.2008 20:27
von Batze
Was ist eigentlich gegen die Übergabe der Struktur die die Daten erthalten soll zu sagen? Das wäre Speichermäßig doch die sauberste Lösung.

Code: Alles auswählen

procedure ByRef(*Output.outputstruct)
*Output\Value1 = #Wasweissich
  ; ...
  ProcedureReturn 1
EndProcedure

ByRef(Out.outputstruct)
; ...

Verfasst: 27.09.2008 20:33
von Josef Sniatecki
@Batze: Dieser weg ist schon gut. Jedoch ist dies nur nützlich für mehrere
Rückgabewerte auf ein Mal. Man sollte möglichst komplexe Ausdrücke
erlauben wie: "x=int(y)+5"

Verfasst: 27.09.2008 22:30
von hjbremer
Wenn das hier ein Anfänger liest, wird er wenig bis nix kapieren, es ist aber gerade für Anfänger wichtig.

in meinen Augen gibt es nur einen korrekten Weg, wenn man Werte übergeben will und diese in einer Prozedur ändern will und anschließend mit diesen geänderten Werten weiterarbeiten will.

Man packe alles in eine Struktur, definiere eine Variable und übergebe diese an eine Prozedur

Abgesehen davon ist dies doch ein altes Thema, die Rückgabe eines Zeigers mit ProcedureReturn der auf eine Variable zeigt, welche in der Prozedur definiert wird, ist Unsinn und wie TSSOFT sagte verboten. Und zwar weil lokale Variablen nach verlassen der Prozedur früher oder später gelöscht bzw. überschrieben werden und der Zeiger dann auf sonstwas zeigt.
Ausser man macht es wie TSSOFT und erklärt diese Variable als Static, nur ist das nicht besonders flexibel.

Hier mal BATZE seinen Beitrag etwas ausführlicher

Code: Alles auswählen

Declare Return4Values(*tVar, x) 
Declare Return4Values2(*tVar, x) 
Declare Return4Values3(*tVar, *tVar2, x) 
Declare Return4Values4(*tvar, x$) 

Structure MyStruct 
  Val1.l 
  Val2.l 
  Val3.d 
  Val4.d 
EndStructure 

;----------------------------------

With Test.MyStruct
  
  \Val1 = 1233
  \Val2 = 124124 
  \Val3 = 1212.213123 
  \Val4 = 1233.123321 

  Return4Values(Test, 2) 

EndWith

Debug Test\Val1 
Debug Test\Val2 
Debug Test\Val3 
Debug Test\Val4 

;oder mit festen Werten in der Prozedur

Return4Values2(Test2.MyStruct, 3) 

Debug Test2\Val1 
Debug Test2\Val2 
Debug Test2\Val3 
Debug Test2\Val4 

;Noch eine Variante mit einer bzw. mehreren Variablen

Return4Values3(@Test3.l, @Test4.d, 3) 

Debug Test3
Debug Test4

;oder mit variablen Strings, es geht aber nur so
;also nicht mit Test5$ oder Test5.s

Return4Values4(Test5.String, "dreifacher") 

Debug Test5\s

End

;-----------------------------------------

Procedure Return4Values(*t.MyStruct, x) 

With *t
  \Val1 * x 
  \Val2 * x 
  \Val3 * x 
  \Val4 * x 
EndWith
   
EndProcedure 

Procedure Return4Values2(*t.MyStruct, x) 

With *t
  \Val1 = x * 1233
  \Val2 = x * 124124 
  \Val3 = x * 1212.213123 
  \Val4 = x * 1233.123321 
EndWith
   
EndProcedure 

Procedure Return4Values3(*v1.long, *v4.double, x) 

  *v1\l = x * 1233
  *v4\d = x * 1233.123321 
   
EndProcedure 

Procedure Return4Values4(*v1.string, x$) 
  
  *v1\s = "Hallo, du " + x$ + " Meuchelmörder" 
   
EndProcedure