Speicher nullen

Anfängerfragen zum Programmieren mit PureBasic.
Sven
Beiträge: 374
Registriert: 23.09.2004 12:01

Speicher nullen

Beitrag von Sven »

Ich schreibe mit SendNetworkString(ClientID, text) einen String an einen Port. Dabei wird laut Hilfe keine 0 ans Ende gestellt. Ist auch sinnvoll, weil sonst folgende Strings verlorengingen, wenn sie geschrieben werden, bevor der Port gelesen wird.

Jetzt lese ich auf der Gegenseite den Port aus.

Code: Alles auswählen

*Buffer = AllocateMemory(65535)
ReceiveNetworkData(connID, *Buffer, 65535)
text.s = PeekS(*Buffer)
Soweit ganz gut. Dummerweise bleibt jetzt der alte String im Speicher. Wenn ein neuer String kommt, der kürzer ist, bekomme ich immer die Reste vom alten String mit, da ja nicht nullterminiert gesendet wird, und die Terminierung beim PeekS nur entsteht, weil der Speicher vorher Null war.

Ich muss also nach dem Auslesen des String den Speicher wieder nullen, aber wie?

eine For-Next über den Speicherbereich jagen?
FreeMemory und erneutest AllocateMemory(65535)?

Beides scheint mir nicht sehr elegant. Sollte das wirklich die Lösung sein? Nach jedem Auslesen des Strings?
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

> FreeMemory und erneutest AllocateMemory(65535)?

sollte das Übliche sein.

Code: Alles auswählen

*Buffer = AllocateMemory(65535)
ReceiveNetworkData(connID, *Buffer, 65535)
text.s = PeekS(*Buffer)
FreeMemory(*Buffer)
gleich wieder freigeben, gar nicht lang rumdümpeln lassen.


... ich glaub, da gabs noch ne API Funktion zum speicher nullen, die beim Allocate mit Nullen zusätzlich aufgerufen wird...
aber k.P. wie die heißt.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Beitrag von STARGÅTE »

Dieses ASM-Stück, gibs hier im Forum, den Autor weiß ich leider nicht mehr:

Code: Alles auswählen

Procedure ClearMemory(*MemoryBuffer, Length)
  !xor eax,eax 
  !mov edi,dword[p.p_MemoryBuffer] 
  !mov ecx,dword[p.v_Length] 
  !mov ebx,ecx 
  !shr ecx,2 
  !rep stosd 
  !mov ecx,ebx 
  !and ecx,3 
  !rep stosb 
EndProcedure
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
Benutzeravatar
hjbremer
Beiträge: 822
Registriert: 27.02.2006 22:30
Computerausstattung: von gestern
Wohnort: Neumünster

Beitrag von hjbremer »

unter Windows

ZeroMemory_(*mem,lg)
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
Benutzeravatar
Vera
Beiträge: 928
Registriert: 18.03.2009 14:47
Computerausstattung: Win XP SP2, Suse 11.1
Wohnort: Essen

Beitrag von Vera »

STARGÅTE hat geschrieben:Dieses ASM-Stück, gibs hier im Forum, den Autor weiß ich leider nicht mehr:
von Thorium ~ siehe hier in ClearMemory(*MemoryBuffer, length)

Gruß ~ Vera
Benutzeravatar
Deluxe0321
Beiträge: 336
Registriert: 19.05.2006 00:31
Kontaktdaten:

Beitrag von Deluxe0321 »

Code: Alles auswählen

*Buffer = AllocateMemory(65535)
Repeat
Empfangen = ReceiveNetworkData(connID, *Buffer, 65535)
text.s + PeekS(*Buffer,Empfangen)
If Not Empfangen = 65535
  Break
EndIf  
ForEver
ReciveNetworkData gibt doch an wieviel Empfangen wurde, warum also den Speicher immer wieder neu erstellen bzw. cleanen?
Ich habe keine Lösung, aber ich bewundere das Problem.
Sven
Beiträge: 374
Registriert: 23.09.2004 12:01

Beitrag von Sven »

Hmpf, natürlich. Das hab ich glatt übersehen. Dann kann ich mir das Nullen freilich sparen.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag von NicTheQuick »

Ich hätte es so gemacht, dass ich vor dem String noch ein Long oder Int sende, dass die
Anzahl der folgenden Bytes oder Zeichen angibt. Dann weiß man schon vor dem eigentlich
String, wie lang er werden muss.

Schließlich kann es auch passieren, dass 'ReceiveNetworkData()' kleinere Blöcke als
angefragt zurückgibt. Und so würde Deluxe0321s Methode auch abbrechen, obwohl der
String noch nicht zu Ende ist.

Wenn man als Empfänger also vorher schon weiß, wieviel kommen wird, kann man weder
zu wenig noch zu viel empfangen. Deswegen müsste es auch von mir noch irgendwo hier
im Forum Procedures geben, die nur zum String-Senden und -Empfangen gedacht waren.

Hier ist der Thread dazu: SendNetworkStructure (muss aber noch angepasst werden)
Benutzeravatar
Deluxe0321
Beiträge: 336
Registriert: 19.05.2006 00:31
Kontaktdaten:

Beitrag von Deluxe0321 »

@NicTheQuick
selbstverständlich, eine Var für die Größe sollte auch mitgesendet werden. Das verhindert auch, dass ein paar böse leute den server Lahmlegen können (wenn auch nur halbwegs) ^^
Ich habe keine Lösung, aber ich bewundere das Problem.
Antworten