Invalid Memory Access, aber warum?

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
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

Beitrag von ts-soft »

Protected entsprich dem Schlüsselwort Local in anderen Sprachen.
Hiermit wird Sicher gestellt, das diese Variable nur innerhalb der Procedure gültig ist und evtl. vorhandene gleichnamige Globale Variablen nicht überschreibt.
Vor allem in Include-Dateien, sowie Code-Bausteinen, sollte für lokale Variablen immer Protected gesetzt werden.
PureBasic 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.
Bild
Benutzeravatar
Konne
Beiträge: 764
Registriert: 30.03.2005 02:20
Kontaktdaten:

Beitrag von Konne »

Ja schon aber wann können Variablen die nicht durch protected geschützt sind konkret verändert werden oder nicht korrekte Werte enthalten?. Mit "wie local in anderen Sprachen kann ich leider wenig anfangen.
Benutzeravatar
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

Beitrag von ts-soft »

Code: Alles auswählen

Global a

Procedure test()
  a = 10
EndProcedure
test()
Debug a

Procedure test2()
  Protected a
  a = 1000
EndProcedure
test2()
Debug a
PureBasic 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.
Bild
Toshy
Beiträge: 713
Registriert: 22.03.2005 00:29
Computerausstattung: Computer und Strom vorhanden
Wohnort: LK Wolfenbüttel

Re: Invalid Memory Access, aber warum?

Beitrag von Toshy »

[quote="zigapeda"]Hi erstmal

Code: Alles auswählen

Procedure.s Getnetworkstring(connectionid)
  *buffer = AllocateMemory(16)
  a = FindString(text,#CRLF$ + #CRLF$,1)
  If a = 0
    Repeat
      ReceiveNetworkData(connectionid,*buffer,16) ;----<---- Diese zeilennummer meldet der debugger
      text + PeekS(*buffer,16) ;----<---- Diese zeile markiert der debugger
      a = FindString(text,#CRLF$ + #CRLF$,1)
    Until a 
  EndIf
  temp.s = Left(text,a+3)
  text = Mid(text,a+4,60-a)
  FreeMemory(*buffer)
  ProcedureReturn temp
EndProcedure
quote]

Wenn die Zeile Markiert wird, dann wird es diese auch sein.
Zum Testen aber einfach mal zwischen receive... und text + eine "sinnlose" zeile einfügen (text = text).
wenn sich die zeilennummer verschiebt ist es die zeile
text + PeekS(*buffer,16)
wenn nicht, dann die andere.

Zwei Fehlerquellen fallen mir aber auf.
du läufst die Schliefe solange durch bis was gefunden wurde.
Da du die länge des Strings nicht überprüfst wird dieser aber wenn das gesuchte Zeichen nicht vorhanden ist bzw. ganz hinten in der datei (dem datensatz) eventl. länger als 64000 Zeichen werden. PB kann aber nur 64000 Zeichen im String verarbeiten.

Der Zweite fehler ist das du keine Bremse eingebaut hast bzw. eine Sicherheitsabfrage. selbst wenn receivenetwork KEINE daten liefert (weil keine empfangen wurden oder WENIGER als 16 zeichen empfangen wurden so liest du IMMER 16 bytes aus und hängst sie auch IMMER and en text an. du hast dann also egal was gesendet wird innerhalb von 1-5 sekunden (je nach CPU) mehr als 64000 zeichen.
und dann wird der speicher überschrieben den du nicht nutzen darfst. früher oder später schmiert dann das programm ab.

Gruß
Thorsten
Toshy
Beiträge: 713
Registriert: 22.03.2005 00:29
Computerausstattung: Computer und Strom vorhanden
Wohnort: LK Wolfenbüttel

Beitrag von Toshy »

Procedure.s Getnetworkstring(connectionid)
*buffer = AllocateMemory(16)
empfangeneDaten.l
a = FindString(text,#CRLF$ + #CRLF$,1)
If a = 0
Repeat
empfangeneDaten = ReceiveNetworkData(connectionid,*buffer,16)
if (empfangeneDaten +len(text)) > 63999 ;63999 wegen abschließendem NULL-Byte
a = -1 ; zuviele Daten für String empfangen
elseif empfangeneDaten > 0
text + PeekS(*buffer,empfangeneDaten)
a = FindString(text,#CRLF$ + #CRLF$,1)
endif
delay(1)
Until a <> 0
EndIf
temp.s = Left(text,a+3)
text = Mid(text,a+4,60-a)
FreeMemory(*buffer)
ProcedureReturn temp
EndProcedure
Antworten