Invalid Memory Access, aber warum?

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
zigapeda
Beiträge: 1753
Registriert: 06.03.2005 17:22
Wohnort: Kaufbeuren
Kontaktdaten:

Invalid Memory Access, aber warum?

Beitrag von zigapeda »

Hi erstmal

warum meldet der Debugger hier Invalid Memory Access?
Ich hoffe einer von euch kann mir helfen, weil die, die ich bisher gefragt hab, konnten mir nicht helfen :cry:
Hier der Code:

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
Noch was: die variable text ist eine Globale, also daran kanns nicht liegen

Schon mal vielen dank für eure hilfe.
kluger Mann + kluge Frau = Romanze | dummer Mann + dumme Frau = Schwangerschaft
kluger Mann + dumme Frau = Affäre | dummer Mann + kluge Frau = Shopping <)
Benutzeravatar
Pinhead
Beiträge: 85
Registriert: 05.09.2005 20:30
Wohnort: HD

Beitrag von Pinhead »

Ich würde erstmal prüfen ob die 16 Bytes wirklich reserviert wurden.

Code: Alles auswählen

*buffer = AllocateMemory(16) 
if *buffer
...

else
...
Endif
Man macht sich immer übertriebene Vorstellungen von dem, was man nicht kennt.
(Albert Camus, franz. Schriftsteller, 1913-1960)
Benutzeravatar
Deeem2031
Beiträge: 1232
Registriert: 29.08.2004 00:16
Wohnort: Vorm Computer
Kontaktdaten:

Beitrag von Deeem2031 »

Benutzt du Threads..?
Vielleicht sind die 16-Bytes auch einfach zu wenig, einfach mal mehr versuchen.
Bild
[url=irc://irc.freenode.org/##purebasic.de]irc://irc.freenode.org/##purebasic.de[/url]
Benutzeravatar
zigapeda
Beiträge: 1753
Registriert: 06.03.2005 17:22
Wohnort: Kaufbeuren
Kontaktdaten:

Beitrag von zigapeda »

@Pinhead ja sie sind adressiert, wenn ich mir den inhalt debuggen las, geht es auch.

@Deeem2031 ich hab auch schon mehr probiert 32, 64 und 512 hatte ich glaub ich auch schon und ich habs auch schon mit nur 8 byte versucht

Trotzdem schon mal danke für die hilfe ;)
kluger Mann + kluge Frau = Romanze | dummer Mann + dumme Frau = Schwangerschaft
kluger Mann + dumme Frau = Affäre | dummer Mann + kluge Frau = Shopping <)
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 »

[c]ReceiveNetworkData()[/c] gibt die Anzahl der in den Buffer
geschriebenen Bytes zurück. Du solltest also mal checken, ob der
Rückgabewert nicht vielleicht kleiner als 16 ist.
Das sollte zwar nicht den Fehler hervorrufen, weil die 16 Bytes ja
trotzdem reserviert sind, aber probiers einfach mal aus.

Und nochwas: Kennst du [c]Protected[/c]? ich würde das an deiner Stelle mal benutzen:

Code: Alles auswählen

Protected *Buffer, a.l, temp.s
Vielleicht kommt sich da irgendwas in die Quere
Team100
Beiträge: 104
Registriert: 13.09.2004 22:59

Beitrag von Team100 »

Du mußt den Rückgabewert von ReceiveNetworkData() auswerten.

ReceiveNetworkData gibt - 1 zurück, wenn aus dem Netzwerks-
Empfangsbuffer nichts zu holen war, und das wird bei einer
Repeat Schleife ohne Delay wohl öfters der Fall sein. :|

Bei erfolgreichem Empfang gibt Dir ReceiveNetworkData() die
tatsächlich empfange Bytezahl zurück, wie Nic bereits geschrieben
hat.

Wird -1 zurückgegeben, dann ist PeekS unzulässig, der alokierte Speicher
sollte auch nicht mehr benutzt werden.

Ungetestet (hab gerade kein Netzwek zur Hand) etwa so sollte es klappen:

Code: Alles auswählen


Repeat 
       
 *buffer = AllocateMemory(16)
  If *buffer 
    result =  ReceiveNetworkData(connectionid,*buffer,16)       
  
    If result > 0
       text + PeekS(*buffer,result) 
       a = FindString(text,#CRLF$ + #CRLF$,1) 
       fehlerzaehler = 0
    Else
       Delay(3)     
       fehlerzaehler + 1                
          IF fehlerzaehler > 2000
            MessageRequester("", "Timeout")
            FreeMemory(*buffer)    
            Break
          Endif
    Endif 
    FreeMemory(*buffer)    
  Else
    MessageRequester("", "zuwenig Speicher")
    Break
  Endif


Until a 

So in etwa, ungetestet, mit Timeout. Was machst Du wenn
dein CRLF nicht kommt ? :lol:

Das ständige Alokieren vom Speicher fällt zeitmäßig nicht sehr
ins Gewicht, da der "Nachschub" vom Netzwerk entschieden langsamer
ist, bietet aber mehr Sicherheit im Störfall.

Nachdem Du den String ohnedies zusammenpfriemelst würde ich
gleich mehr Speicher alokieren .... es sei denn Du hast auf Deinem
PC Speichermangel :mrgreen:

Das String-Limit wäre auch noch zu beachten .....

Eleganter wäre es vor dem String einen Header zu senden, der zumindest
die zu erwartende Stringlänge angibt. Du bist dann auf das CRLF
nicht angewiesen und kannst auch einen ProgressBar einrichten.

Cu von Team100
Kompliziert kann es jeder lösen, aber das wirklich Geniale ist einfach.....
Benutzeravatar
Tafkadasom2k5
Beiträge: 1578
Registriert: 13.08.2005 14:31
Kontaktdaten:

Beitrag von Tafkadasom2k5 »

Ein bissl offtopic - Topic:

Was genau macht "AllocateMemory()" denn?

Code: Alles auswählen

*buffer = AllocateMemory(16)
Macht doch eigentlich nichts anderes als:
16Bytes reservieren, und den Pointer dieser Addresse an "buffer" zu geben.Aber warum ist vor "buffer" ein "*"? Muss das, damit man erkennt "hier steckt ein Pointer drinn"?

In der Hoffnung, dass keiner angevernt von meinen Anfängerfragen ist:

Tafkadasom2k5
OpenNetworkConnection() hat geschrieben:Versucht eine Verbindung mit dem angegebenen Server aufzubauen. 'ServerName$' kann eine IP-Adresse oder ein voller Name sein (z.B.: "127.0.0.1" oder "ftp.home.net").
php-freak hat geschrieben:Ich hab die IP von google auch ned rausgefunden!
Benutzeravatar
Deeem2031
Beiträge: 1232
Registriert: 29.08.2004 00:16
Wohnort: Vorm Computer
Kontaktdaten:

Beitrag von Deeem2031 »

Tafkadasom2k5 hat geschrieben:Was genau macht "AllocateMemory()" denn?

Code: Alles auswählen

*buffer = AllocateMemory(16)
Macht doch eigentlich nichts anderes als:
16Bytes reservieren, und den Pointer dieser Addresse an "buffer" zu geben.Aber warum ist vor "buffer" ein "*"? Muss das, damit man erkennt "hier steckt ein Pointer drinn"?
Wenn du den pointer nur weitergeben willst, kannst du das "*" auch weglassen. Die meisten (ich nich ;) ) schreiben den aber trotzdem hin damit mal als Progger sieht das es ein Pointer ist, dem Compiler ist das relativ egal, der einzige Unterschied für ihn das die eine Var intern "v_buffer" heißt, die andere "p_buffer".
Bild
[url=irc://irc.freenode.org/##purebasic.de]irc://irc.freenode.org/##purebasic.de[/url]
Benutzeravatar
zigapeda
Beiträge: 1753
Registriert: 06.03.2005 17:22
Wohnort: Kaufbeuren
Kontaktdaten:

Beitrag von zigapeda »

Team100 hat geschrieben:Eleganter wäre es vor dem String einen Header zu senden, der zumindest
die zu erwartende Stringlänge angibt. Du bist dann auf das CRLF
nicht angewiesen und kannst auch einen ProgressBar einrichten.
Hmm also das ergebniss ausgewertet hab ich, und da ist mir was aufgefallen...
beim ersten mal wird 14 gedebuggt
beim zweiten mal -1, normal müsste er gleich danach aufhören, tut er aber nicht statt dessen debuggt er noch unzählige male -1 und meldet dann erst invalid memory access.
mein fehler war das es zwar einen zeilenumbruch gibt, aber der client, der hier connectet anscheinend ein anderes format benutzt also #CRLF$ nicht auffindbar ist oO

@NTQ ja das mit Protect kenn ich, das hab ich erst neulich mal entdeckt ;) aber ich hab bis jetzt immer darauf geachtet das alle variablen einen anderen namen haben

So jetzt nochmal allen Danke fürs kopf zerbrechen weil eigentlich war es ja ein fehler meinerseits :oops:
kluger Mann + kluge Frau = Romanze | dummer Mann + dumme Frau = Schwangerschaft
kluger Mann + dumme Frau = Affäre | dummer Mann + kluge Frau = Shopping <)
Benutzeravatar
Konne
Beiträge: 764
Registriert: 30.03.2005 02:20
Kontaktdaten:

Beitrag von Konne »

Nur mal ne kleinen Verständnisfrage:
Protected macht doch dass man Globale Variablen auch in der Procedure genullt verwenden kann, oda? Gibt es nch andere Fälle wo es auftreten kann das Protected was hilft?
Antworten