Probleme violation de la mémoire [Résolu]

BrokenArrow29 110 Messages postés vendredi 1 décembre 2006Date d'inscription 14 décembre 2011 Dernière intervention - 11 oct. 2007 à 21:11 - Dernière réponse : surfzoid 467 Messages postés vendredi 15 août 2003Date d'inscription 21 avril 2010 Dernière intervention
- 11 mars 2008 à 18:21
Bonjour,
j'obtiens cette erreur lorsque j'éxécute un petit programme :
"L'exception System.AccessViolationException n'a pas été gérée
Tentative de lecture ou d'écriture de mémoire protégée. Cela indique souvent qu'une autre mémoire est endommagée."
Détail: System.AccessViolationException
"
Le programme lit une base de donnée et cherche le correspondant dans une autre base de donnée. L'erreur n'arrive jamais au meme endroit ou au meme enregistrement. Parcontre elle arrive toujours lorsque par une fonction (contenu dans un dll qui est en référence) attribue une valeur a une variable. C'est un peu weird ...

Merci de votre aide
Afficher la suite 

14 réponses

Répondre au sujet
cs_casy 7745 Messages postés mercredi 1 septembre 2004Date d'inscription 24 septembre 2014 Dernière intervention - 12 oct. 2007 à 20:44
+3
Utile
ALors déjà effectivement, comme je disais, tu n'instancie pas correctement tes string avant l'appel. Certes tu les instancies mais de longueur nulle. C'est à dire qu'aucune place n'est réservée en mémoire pour contenir la chaine de caractère. Hors il est probable que ta dll ne soit pas capable de créer une string en mémoire, elle doit juste se contenter (comme la quasi totalité des dlls api) de remplir une zone mémoire déjà occupée par la string à remplir. Dans ce cas là, avant de passer la string à la fonction, il faut veiller à ce que une zone mémoire suffisament grande est effectivement occupée par la dite string, c'est à dire que la string soit de longueur suffisament importante pour acceuillir sa nouvelle valeur.
Dans ton cas, si tant est que ce soit ça le problème, il faut que avant chaque appel, tu initialise chacune des strings avec suffisament de caractères pour que la zone réservée en mémoire soit suffisament grande. Ce qui donnerais le code suivant :

Dim PLAYERFIRST As String
Dim PLAYERCITY As String
Dim PLAYERLAST As String
Dim PLAYERindx As Integer =  0

'PARTIE  DE CODE

'HandleEXH est
mon fichier ouvert de base de donnée.
For I = 0 To (TABLEINFO.RecordCount - 1)

        PLAYERFIRST = New String(vbNullChar, 100)
        PLAYERLAST = New String(vbNullChar, 100)
        PLAYERCITY = New String(vbNullChar, 100)
        PLAYERindx = New String(vbNullChar, 100)

        TDBFieldGetValueAsString(HandleEXH, "SPBT", "FNME", I, PLAYERFIRST)
        TDBFieldGetValueAsString(HandleEXH, "SPBT", "LNME", I, PLAYERLAST)
        TDBFieldGetValueAsString(HandleEXH, "SPBT", "CITY", I, PLAYERCITY)
        TDBFieldGetValueAsString(HandleEXH, "SPBT", "INDX", I, PLAYERindx)

Next

Autre problème possible :
Il te faut vérifier que la ligne de déclaration de ta dll correspond bien à une déclaration pour VB2005 et non pas VB6. En effet entre VB6 et VB2005, le type de variable a changé. Ainsi les integer (vb6) deviennent des short (ou Int16) en VB2005, les longs deviennent des integers.

Si donc ta déclaration avec des integers est prevu ppour VB6, pour l'utiliser avec VB2005, il te faut remplcer les integer par des shorts ou des Int16.

En espérant ne pas t'avoir trop embrouiller

---- Sevyc64  (alias Casy) ---- <hr size ="2" width="100%" /># LE PARTAGE EST NOTRE FORCE #   
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de cs_casy
GEDDi 209 Messages postés lundi 22 novembre 1999Date d'inscription 3 juillet 2008 Dernière intervention - 11 oct. 2007 à 21:14
0
Utile
Ya fort à parier que ça vienne de la DLL, genre mémoire mal allouée, libération de mémoire anticipée, tentative d'acces à une zone mémoire qui a déjà été effacée mais dont le pointeur n'a pas été mis à NULL, ce genre de choses codées par des gruic gruiiic :)

Gérôme GUILLEMIN
Auteur du langage FBSL
Commenter la réponse de GEDDi
cs_casy 7745 Messages postés mercredi 1 septembre 2004Date d'inscription 24 septembre 2014 Dernière intervention - 11 oct. 2007 à 21:52
0
Utile
Moi je parirais plus pour un problème d'appel à la dll.

Je ne pense pas que ce soit la dll qui est en cause, mais plutot la façon dont tu t'en sert.

---- Sevyc64  (alias Casy) ---- # LE PARTAGE EST NOTRE FORCE #   
Commenter la réponse de cs_casy
BrokenArrow29 110 Messages postés vendredi 1 décembre 2006Date d'inscription 14 décembre 2011 Dernière intervention - 11 oct. 2007 à 22:48
0
Utile
c'est que l'appel de la fonction (qui est storé dans la dll ) est dans une boucle qui va tournée autant fois qu'il ya des donnée dans la bd (genre 5 000 fois). Mais elle va donnée l'erreur des fois Exemple au 3000ieme enregistement sur le champ B et d'autre fois au 2800ieme sur un autre champ. Les fois d'avant elle fonctionne bien... Il semble pas avoir de relation avec le champ ou la donnée lu. Sa me semble comme si y aurais pas de mémoire disponible additionnelle. Pourtant j'ai 2gig de mémoire.
Commenter la réponse de BrokenArrow29
cs_casy 7745 Messages postés mercredi 1 septembre 2004Date d'inscription 24 septembre 2014 Dernière intervention - 11 oct. 2007 à 22:53
0
Utile
Tu es en VB2005, comment déclare-tu les fonctions de ta dll ??? Il se peut que le type de variable que tu lui passe ne corresponde pas à ce qu'elle attent.

Autre point, est-ce que tes variables sont correctement instanciées avant de les passer à la dll. Ex, si tu lui passe une chaine de caractère qu'elle doit remplir, cette chaine doit au préalable etre correctement remplie avec suffisament de caractères pour qu'elle existe en mémoire.

Le mieux est que tu mette le bout de code qui pose problème.

---- Sevyc64  (alias Casy) ---- # LE PARTAGE EST NOTRE FORCE #   
Commenter la réponse de cs_casy
BrokenArrow29 110 Messages postés vendredi 1 décembre 2006Date d'inscription 14 décembre 2011 Dernière intervention - 12 oct. 2007 à 18:21
0
Utile
Voila ma déclaration de la fonction de la dll

Public
Declare
Function TDBFieldGetValueAsString
Lib
"F:\filedll\tdbaccess.dll" (
ByVal DBIndex
As
Integer,
ByVal TableName
As
String,
ByVal FieldName
As
String,
ByVal RecNo
As
Integer,
ByRef OutBuffer
As
String)
As
Boolean



Variable déclarer dans ma procedure


Dim



PLAYERFIRST
As


String
=
""
Dim PLAYERCITY AsString = ""
Dim PLAYERLAST
As
String =
""
Dim PLAYERindx
As
Integer = 0


'PARTIE  DE CODE

'HandleEXH est mon fichier ouvert de base de donnée.
For
I = 0
To (TABLEINFO.RecordCount - 1)   TDBFieldGetValueAsString(HandleEXH,

"SPBT",
"FNME", I, PLAYERFIRST)
    TDBFieldGetValueAsString(HandleEXH,
"SPBT",
"LNME", I, PLAYERLAST)
   TDBFieldGetValueAsString(HandleEXH,
"SPBT",
"CITY", I, PLAYERCITY)
   TDBFieldGetValueAsString(HandleEXH,
"SPBT",
"INDX", I, PLAYERindx)

L'erreur peut arriver a n'importe quelle ligne des fonction TDBfield.. c'est aléatoire jusqu'a maintenant. Et sur n'importe quel enregistrement(la valeur de I est différence a chaque erreur.) La fonction TDBfield lit une valeur dans la table SPBT, sur le champ FNME etc. à l'enregistrement I et la place dans la variable au bout ex: PLAYERFIRST.

Voilà je ne sais pas si vous avez assez d'info pour m'aider
Merci!!!!!.
Commenter la réponse de BrokenArrow29
BrokenArrow29 110 Messages postés vendredi 1 décembre 2006Date d'inscription 14 décembre 2011 Dernière intervention - 12 oct. 2007 à 21:25
0
Utile
Merci, Merci 
ca fonctionne tres bien lorsque j'initialise la variable a chaque tour. C'est un détail que j'avais vue.

J'ai perdue une semaine à fouiller et changer mes procedures pour que tu me fasse découvrir qu'il fallait initialiser la variable a chaque tour de la routine pour la dll peuvent y inclure l'info.

Mais est ce type a visual studio 2005 ou si je l'avais fais en Vb6 ca aurait fonctionner sans l'initialiser a chaque tour ?
Commenter la réponse de BrokenArrow29
cs_casy 7745 Messages postés mercredi 1 septembre 2004Date d'inscription 24 septembre 2014 Dernière intervention - 12 oct. 2007 à 21:42
0
Utile
Ca aurait été exactement pareil en VB6, c'est d'ailleurs comme ça que l'on fait lorsque l'on utilise les fonctions de l'api Windows.

Ceci est dû à la spécificité des variables de type string. Pour la pluspart des variables simples, ta variable dans le code représente une zone mémoire ou est réellement stocké la valeur de ta variable. Dans le cas des strings, la variable dans le code représente en mémoire, non pas une zone ou est stocké la chaine de caractère, mais une zone ou est stocké l'adresse d'une autre zone mémoire qui elle contiendra réellement la chaine de caractère. Dû au fonctionnement du traitement des string, cette derbière zone change en permanence de place, il est donc plus facile de stocké dans une variable fixe l'adresse d'une zone mémoire plutot que de modifier en permanance la position de cette variable et ainsi planter le programme qui aurait du mal à retrouver cette variable.

Pour ce qui est des dll, comme je te disais, généralement elles ne sont pas capable de créer de zone mémoire ou stockées les chaines. Elles ne font que copier les caractères dans une zone qui leurs a été indiqué. Mais si cette zone n'existe pas (string de longueur nulle par exemple) ou qu'elle est trop courte, la dll n'est pas capable de le savoir et va allègrement déborder sur les données qui suivent en les détruisant. Ces données étant corrompues, cela provoque soit un plantage, soit des erreurs, soit des violation d'accès.

C'est pour cela que lorsque tu passe une chaine de caractère à une dll de ce type qui doit y écrire dedant, cette chaine doit avoir au préalable été remplie pour qu'elle ait une longueur au moins égale (mais de préférence plus) que le nombre de caractères que va écrire la dll.

---- Sevyc64  (alias Casy) ---- # LE PARTAGE EST NOTRE FORCE #   
Commenter la réponse de cs_casy
BrokenArrow29 110 Messages postés vendredi 1 décembre 2006Date d'inscription 14 décembre 2011 Dernière intervention - 12 oct. 2007 à 22:32
0
Utile
Merci très claire, très bien expliqué
Commenter la réponse de BrokenArrow29
surfzoid 467 Messages postés vendredi 15 août 2003Date d'inscription 21 avril 2010 Dernière intervention - 11 déc. 2007 à 21:41
0
Utile
Mon sauveur, j'écrit CS-Obexftp(sf.net) et je les même symptomes, je galére depuis le debut et j'utilise une dll en C.
Merci
Commenter la réponse de surfzoid
maximechaput 2 Messages postés mercredi 14 février 2007Date d'inscription 11 mars 2008 Dernière intervention - 6 mars 2008 à 18:21
0
Utile
claude 
J'avais le meme probleme je l'ai résolu en changant le type des paramtre
ex.: ByVal variable as long en ByVal variable as int32
j'ai eu plusieur bug avec les api(Dll) et j'ai du changer les types des parametre passé  en Int32

si tu connait OLLY
tu execute le prog. sous olly et met un Breakpoint leur l'api que tu appelle et va voir si tes parametre sont bien typer.

Si tu peu me laisser un email je serait content de savoir si cela ta aider
Commenter la réponse de maximechaput
surfzoid 467 Messages postés vendredi 15 août 2003Date d'inscription 21 avril 2010 Dernière intervention - 7 mars 2008 à 10:13
0
Utile
il faudra que je test, olly c'est pour win32 ? tu le trouve ou ?
Ton prob sur le format de variable, il te faisait une erreur memoire systematique ou de façon complétement alléatoire ?
Commenter la réponse de surfzoid
maximechaput 2 Messages postés mercredi 14 février 2007Date d'inscription 11 mars 2008 Dernière intervention - 11 mars 2008 à 16:46
0
Utile
claude


Olly est sur internet tape  Ollydbg et fait une recherche
 lorsque tu entre les types des parametres si tu tu as un int 16 au lieu d'un int32.

l'api de la dll récupere pas la bonne adresse
donc au lieu d'aller lire en mémoire voulu il va lire sur une mémoire que se trouve sur pile car les valeurs récupérer par l'api sont biaiser

je te suggere fortement de te procurer OLLY avec ca va pouvoir t'assurer des parametre que tu
entre pour n'importe quelle api sont exact
et va comprendre pouquoi que l'appel des api sont aussi bizarre

En passant OLLY est le debugger utiliser par 90% de ceux qui decortique le code assembleur
tu n'aura pas besoin d'en connaiter beaucoup pour l'utiliser pour suivre les parametre passer au api de dll
si tu t'en serre envoi moi un email et je te dirai comment té,en servir pour suivre les api utiliser dans les
programmes comme visual basic et c++.

j'ai aussi remarquer que plusieurs api sur internet était mal documenter donc assure toi que tu as les bonnes informations

A la prochaine et bonne chance.
Commenter la réponse de maximechaput
surfzoid 467 Messages postés vendredi 15 août 2003Date d'inscription 21 avril 2010 Dernière intervention - 11 mars 2008 à 18:21
0
Utile
Merci
En fait je travail en colaboration avec l'equipe qui a ecrit la dll en C, mais a l'origine c'est une librairie Linux qui a été "porté" sous windows, bien entendu tout nouveau est accepté dans l'équipe, car c'est de l'opensource, tu serai d'accord (si comme tjr, le temp le permet) de participé ?
Commenter la réponse de surfzoid

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.