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

Messages postés
110
Date d'inscription
vendredi 1 décembre 2006
Dernière intervention
14 décembre 2011
- - Dernière réponse : surfzoid
Messages postés
467
Date d'inscription
vendredi 15 août 2003
Dernière intervention
21 avril 2010
- 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 

Votre réponse

14 réponses

Meilleure réponse
Messages postés
7745
Date d'inscription
mercredi 1 septembre 2004
Dernière intervention
24 septembre 2014
3
Merci
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 #   

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources a aidé 106 internautes ce mois-ci

Commenter la réponse de cs_casy
Messages postés
209
Date d'inscription
lundi 22 novembre 1999
Dernière intervention
3 juillet 2008
0
Merci
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
Messages postés
7745
Date d'inscription
mercredi 1 septembre 2004
Dernière intervention
24 septembre 2014
0
Merci
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
Messages postés
110
Date d'inscription
vendredi 1 décembre 2006
Dernière intervention
14 décembre 2011
0
Merci
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
Messages postés
7745
Date d'inscription
mercredi 1 septembre 2004
Dernière intervention
24 septembre 2014
0
Merci
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
Messages postés
110
Date d'inscription
vendredi 1 décembre 2006
Dernière intervention
14 décembre 2011
0
Merci
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
Messages postés
110
Date d'inscription
vendredi 1 décembre 2006
Dernière intervention
14 décembre 2011
0
Merci
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
Messages postés
7745
Date d'inscription
mercredi 1 septembre 2004
Dernière intervention
24 septembre 2014
0
Merci
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
Messages postés
110
Date d'inscription
vendredi 1 décembre 2006
Dernière intervention
14 décembre 2011
0
Merci
Merci très claire, très bien expliqué
Commenter la réponse de BrokenArrow29
Messages postés
467
Date d'inscription
vendredi 15 août 2003
Dernière intervention
21 avril 2010
0
Merci
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
Messages postés
2
Date d'inscription
mercredi 14 février 2007
Dernière intervention
11 mars 2008
0
Merci
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
Messages postés
467
Date d'inscription
vendredi 15 août 2003
Dernière intervention
21 avril 2010
0
Merci
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
Messages postés
2
Date d'inscription
mercredi 14 février 2007
Dernière intervention
11 mars 2008
0
Merci
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
Messages postés
467
Date d'inscription
vendredi 15 août 2003
Dernière intervention
21 avril 2010
0
Merci
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.