es reicht ja nicht ein FreeMemory(*Test), sonder er muss es immer machen bevor er den "alten" Pointer überschreibt, um ihn nicht zu verlieren.
Dinge, die ich nicht wusste
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.

es reicht ja nicht ein FreeMemory(*Test), sonder er muss es immer machen bevor er den "alten" Pointer überschreibt, um ihn nicht zu verlieren.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Ich mach das schon absichtlich so... die paar Bytes kann der Arbeitsspeicher schon verschmerzen...
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:
Wenn ich das ganze in einer Schleife mache gebe ich sowiso immer den alten Speicher vorher frei, das muss man dann halt manuel machen.
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
Zuletzt geändert von cxAlex am 27.09.2008 19:35, insgesamt 1-mal geändert.
Projekte: IO.pbi, vcpu
Pausierte Projekte: Easy Network Manager, µC Emulator
Aufgegebene Projekte: ECluster

PB 5.1 x64/x86; OS: Win7 x64/Ubuntu 10.x x86
Pausierte Projekte: Easy Network Manager, µC Emulator
Aufgegebene Projekte: ECluster
PB 5.1 x64/x86; OS: Win7 x64/Ubuntu 10.x x86
-
DarkDragon
- Beiträge: 6291
- Registriert: 29.08.2004 08:37
- Computerausstattung: Hoffentlich bald keine mehr
- Kontaktdaten:
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".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.
Angenommen es gäbe einen Algorithmus mit imaginärer Laufzeit O(i * n), dann gilt O((i * n)^2) = O(-1 * n^2) d.h. wenn man diesen Algorithmus verschachtelt ist er fertig, bevor er angefangen hat.
So hier eine ERLAUBTE (
) Version meines Codes:
Jetzt wird der alte Speicher immer Freigegeben.
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\Val4Projekte: IO.pbi, vcpu
Pausierte Projekte: Easy Network Manager, µC Emulator
Aufgegebene Projekte: ECluster

PB 5.1 x64/x86; OS: Win7 x64/Ubuntu 10.x x86
Pausierte Projekte: Easy Network Manager, µC Emulator
Aufgegebene Projekte: ECluster
PB 5.1 x64/x86; OS: Win7 x64/Ubuntu 10.x x86
- ts-soft
- Beiträge: 22292
- Registriert: 08.09.2004 00:57
- Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel - Wohnort: Berlin
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\Val4PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.

Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.

-
DarkDragon
- Beiträge: 6291
- Registriert: 29.08.2004 08:37
- Computerausstattung: Hoffentlich bald keine mehr
- Kontaktdaten:
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.ts-soft hat geschrieben:reicht das nicht?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
Angenommen es gäbe einen Algorithmus mit imaginärer Laufzeit O(i * n), dann gilt O((i * n)^2) = O(-1 * n^2) d.h. wenn man diesen Algorithmus verschachtelt ist er fertig, bevor er angefangen hat.
So verlierst du aber die alten Werte:
Weil alle Werte auf den selben Speicher zeigen.
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
Projekte: IO.pbi, vcpu
Pausierte Projekte: Easy Network Manager, µC Emulator
Aufgegebene Projekte: ECluster

PB 5.1 x64/x86; OS: Win7 x64/Ubuntu 10.x x86
Pausierte Projekte: Easy Network Manager, µC Emulator
Aufgegebene Projekte: ECluster
PB 5.1 x64/x86; OS: Win7 x64/Ubuntu 10.x x86
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)
; ...- Josef Sniatecki
- Beiträge: 657
- Registriert: 02.06.2008 21:29
- Kontaktdaten:
@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"
Rückgabewerte auf ein Mal. Man sollte möglichst komplexe Ausdrücke
erlauben wie: "x=int(y)+5"
PB 4.61 | Windows Vista - 32Bit
Homepage
"Wahrlich es ist nicht das Wissen, sondern das Lernen, nicht das Besitzen sondern das Erwerben, nicht das Dasein, sondern das Hinkommen, was den grössten Genuss gewährt." - Carl Friedrich Gauß
Homepage
"Wahrlich es ist nicht das Wissen, sondern das Lernen, nicht das Besitzen sondern das Erwerben, nicht das Dasein, sondern das Hinkommen, was den grössten Genuss gewährt." - Carl Friedrich Gauß
- hjbremer
- Beiträge: 822
- Registriert: 27.02.2006 22:30
- Computerausstattung: von gestern
- Wohnort: Neumünster
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
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
Purebasic 5.70 x86 5.72 X 64 - Windows 10
Der Computer hat dem menschlichen Gehirn gegenüber nur einen Vorteil: Er wird benutzt
grüße hjbremer
Der Computer hat dem menschlichen Gehirn gegenüber nur einen Vorteil: Er wird benutzt
grüße hjbremer