Invalid acces memory étrange[résolu]

Programmation d'applications complexes
Anonyme

Invalid acces memory étrange[résolu]

Message par Anonyme »

Voila , j'appelle une fonction qui me créer un engrenage
cette fonction me retourne un pointeur , je l'utilise pour identifier l'engrenage.
mais lorsque je veut créer un deuxième engrenage , j'ai un "invalid memory" qui apparait sur un allocatememory()...

Voila le code :

Code : Tout sélectionner

InitSprite() : InitKeyboard() : InitMouse() : InitSprite3D()
  OpenScreen(800,600,32,"") : UsePNGImageDecoder()
  
  Structure Vertex
    x.f
    y.f
  EndStructure
  
  Structure Engrenage
   *Vertices.i
   NbVertices.i
   x.f
   y.f
   Angle.f
   Radius.l
  EndStructure
  
  Procedure.i MakeEngrenage(X,Y,Radius,NbTheet,TheetHeight)
  
  Protected Sub = 5
  Protected AngleStep = 360 / ((NbTheet*2)*Sub)

  *E.Engrenage  = AllocateMemory(  SizeOf(Engrenage) )
  *E\Vertices       = AllocateMemory(  SizeOf(Vertex) * AngleStep  )
  *E\NbVertices = 360 / AngleStep
  *E\Radius =Radius
   *E\x = X
   *E\y = Y
   Radius_ = Radius
   
  For i = 0 To 360  / AngleStep
 
    C+1
    C%Sub

    
    If C=Sub-1
    D+1
    D%2      
    
      If D=1
        Radius_ = Radius +TheetHeight
      EndIf
      
       If D=0
        Radius_ = Radius 
      EndIf
       
    EndIf 
 
  X_.f = X + Radius_ * Cos( ( i * AngleStep) * #PI / 180 )
  Y_.f = Y + Radius_ * Sin ( ( i * AngleStep) * #PI / 180 )
 
 PokeF(*E\Vertices+ ( i * SizeOf(Vertex) + OffsetOf(Vertex\x)) ,X_ )
 PokeF(*E\Vertices+ ( i * SizeOf(Vertex) + OffsetOf(Vertex\y)) ,Y_ )
    
  Next 
  
  ProcedureReturn *E  
  EndProcedure
  
  Procedure DrawEngrenage(*Engrenage.Engrenage)
  StartDrawing(ScreenOutput())
  With  *Engrenage
       For i = 0 To \NbVertices-1
          x1.f = PeekF(\Vertices + ( i *SizeOf(Vertex) + OffsetOf(Vertex\x))) 
          y1.f = PeekF(\Vertices + ( i *SizeOf(Vertex) + OffsetOf(Vertex\y)))
          
          x2.f = PeekF(\Vertices + ( (i+1) *SizeOf(Vertex) + OffsetOf(Vertex\x))) 
          y2.f = PeekF(\Vertices + ( (i+1) *SizeOf(Vertex) + OffsetOf(Vertex\y)))
          
          LineXY(x1,y1,x2,y2,$000000)
                                
      Next 
      
      ; On ferme
      
          x1 = PeekF(\Vertices + ( 1*SizeOf(Vertex) + OffsetOf(Vertex\x))) 
          y1 = PeekF(\Vertices + ( 1*SizeOf(Vertex) + OffsetOf(Vertex\y)))
          
          x2 = PeekF(\Vertices + ( \NbVertices *SizeOf(Vertex) + OffsetOf(Vertex\x))) 
          y2 = PeekF(\Vertices + ( \NbVertices *SizeOf(Vertex) + OffsetOf(Vertex\y)))
          
          LineXY(x1,y1,x2,y2,$000000)
      
      DrawingMode(#PB_2DDrawing_Outlined)
          Circle(\X,\Y,\Radius/1.5,$000000)
      
      
      
  EndWith
  StopDrawing()
  EndProcedure
  
  

  
  

  A= MakeEngrenage(400,300,150,10,20)
  Debug "A ok"
  B =  MakeEngrenage(400,300,150,10,20)
  Debug "B ok"
  
  Repeat
    ExamineKeyboard()
      ClearScreen($FFFFFF)
      
      
      
            DrawEngrenage(A)
            DrawEngrenage(B) 
            
    FlipBuffers(0)
  Until KeyboardPushed(#PB_Key_Escape)
Dernière modification par Anonyme le mer. 14/janv./2009 23:13, modifié 1 fois.
tmyke
Messages : 1554
Inscription : lun. 24/juil./2006 6:44
Localisation : vosges (France) 47°54'39.06"N 6°20'06.39"E

Message par tmyke »

En regardant vite fait, ligne 32, ta boucle

Code : Tout sélectionner

For i = 0 To 360  / AngleStep
donne forcement plus d'itération que de AllocateMemory( SizeOf(Vertex) * AngleStep ) aloué,
vue que 360/AngleStep est > à AngleStep
donc violation mémoire dans cette boucle quand tu fait tes

Code : Tout sélectionner

 PokeF(*E\Vertices+ ( i * SizeOf(Vertex) + OffsetOf(Vertex\x)) ,X_ )
 PokeF(*E\Vertices+ ( i * SizeOf(Vertex) + OffsetOf(Vertex\y)) ,Y_ )
Le fait que cela plante lors d'une tentative de seconde allocation d'un Engrenage est trompeur,
car l'erreur se produit en fait lors des opérations sur le premier.
Force et sagesse...
Anonyme

Message par Anonyme »

Merci , mais le problème persite , j'ai corrigé une partie de mon erreur :
Protected Sub = 5
Protected AngleStep = 360 / ((NbTheet*2)*Sub)

*E.Engrenage = AllocateMemory( SizeOf(Engrenage) )
*E\Vertices = AllocateMemory( SizeOf(Vertex) * (360 / AngleStep) )

Qui pour 100 vertices alloue bien 800 bytes de mémoire.
L'allocation plante là on c'est en gras. lors du second appel , j'ai beau agrandir artificiellement la taille de mémoire , ca ne change rien.
tmyke
Messages : 1554
Inscription : lun. 24/juil./2006 6:44
Localisation : vosges (France) 47°54'39.06"N 6°20'06.39"E

Message par tmyke »

En effet cela plante toujours.

En fait il semble que l'allocation soit enore trop 'courte' et d'ailleurs en commentant les Poke, cela
ne plante plus. C'est bien que c'est ligne vont écrire ou il ne faut pas.

Je viens de voir la ligne

Code : Tout sélectionner

  For i = 0 To 360  / AngleStep
en la remplaçant par

Code : Tout sélectionner

  For i = 0 To (360  / AngleStep)-1

cela parait plus logique, et de plus le code ne plante plus et j'ai une belle roue denté à l'ecran.
Force et sagesse...
lionel_om
Messages : 1500
Inscription : jeu. 25/mars/2004 11:23
Localisation : Sophia Antipolis (Nice)
Contact :

Message par lionel_om »

J'ai déjà eu des pb de ce genre.
Pour débugger on peut utiliser ça (code eu sur le forum anglais) :

Code : Tout sélectionner

Procedure ValidatePBHeap(LineNumber)
  Protected Heap
  !mov eax, dword [_PB_MemoryBase]
  !mov [p.v_Heap], eax
  If HeapValidate_(Heap, 0, 0) = 0
    MessageRequester("Error", "PB Memory Heap invalid at Line:  " +Str(LineNumber))
  EndIf 
EndProcedure 

Macro _validate
  ValidatePBHeap(#PB_Compiler_Line)
EndMacro
Il n'y a plus qu'à utiliser '_validate' à plusieurs endroit pour voir où ca plante...

/Lio
Webmestre de Basic-univers
Participez à son extension: ajouter vos programmes et partagez vos codes !
lionel_om
Messages : 1500
Inscription : jeu. 25/mars/2004 11:23
Localisation : Sophia Antipolis (Nice)
Contact :

Message par lionel_om »

C'est tes PokeF() qui sont en cause (dans MakeEngrenage() ).
Dans ton exemple, tu réserves 24 octets pour *E\Vertices, or dans ta boucle For/Next, tu vas bien plus loin que ces 24...jusqu'à 964.

Regarde de ce coté...

J'ai mis la taille à 2000 et ca marche...

/Lio
Webmestre de Basic-univers
Participez à son extension: ajouter vos programmes et partagez vos codes !
Anonyme

Message par Anonyme »

Oui , j'ai déjà corrigé le problème.
le problème venais de là et de la boucle for - next
merci les gens , on en apprend tout les jours. :D
Répondre