Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
2430 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  [MFC] Violation d'accès en lecture ? pourquoi ?

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[MFC] Violation d'accès en lecture ? pourquoi ?

n°1027418
Pwill
Deux fois Né
Posté le 28-03-2005 à 16:47:52  profilanswer
 

:hello:
J'ai un petit soucis avec mes Sockets  :ange:  
 
J'ai un projet sous visual C++: un tableau blanc qui fonctionne en réseau (on dessine chacun de son côté et ca apparait de part et d'autre).
 
J'ai donc un projet avec une classe TableauBlancDoc et une classe TableauBlancView qui hérite de CScrollView.
J'ai une classe TableauBlancSocket qui hérite de CSocket et dans laquelle j'ai un membre de type
TableauBlancView* .
Le but de la classe TableauBlancSocket est de redéfinir OnClose() et OnReceive().
 

Code :
  1. // TableauBlancSocket.cpp : fichier d'implémentation
  2. //
  3. #include "stdafx.h"
  4. #include "Tableau Blanc.h"
  5. #include "TableauBlancSocket.h"
  6. #include ".\tableaublancsocket.h"
  7. #include "Tableau BlancView.h"
  8. // CTableauBlancSocket
  9. CTableauBlancSocket::CTableauBlancSocket()
  10. {
  11. m_View=NULL;
  12. }
  13. CTableauBlancSocket::~CTableauBlancSocket()
  14. {
  15. }
  16. // Fonctions membres CTableauBlancSocket
  17. CTableauBlancSocket::CTableauBlancSocket(CTableauBlancView* v)
  18. {
  19. m_View=v;
  20. }
  21. void CTableauBlancSocket::OnReceive(int nErrorCode)
  22. {
  23. // TODO : ajoutez ici votre code spécialisé et/ou l'appel de la classe de base
  24. if (m_View=NULL) return;
  25. m_View->ProcessPendingRead();
  26. CSocket::OnReceive(nErrorCode);
  27. }
  28. void CTableauBlancSocket::OnClose(int nErrorCode)
  29. {
  30. // TODO : ajoutez ici votre code spécialisé et/ou l'appel de la classe de base
  31. if (m_View==NULL) return;
  32. m_View->ProcessPendingClose();
  33. CSocket::OnClose(nErrorCode);
  34. }


 
 
J'ai une fonction de connection dans mon TableauBlancView.cpp ainsi:
 

Code :
  1. void CTableauBlancView::Connecte()
  2. {
  3. GetDlgItem(ID_CONNEXION_CONNEXION)->EnableWindow(false);
  4. BConnecte=true;
  5. if(GetDocument()->ModeAppli)
  6. {
  7.  //mode serveur
  8.  Serv = new CTableauBlancSocket(this);
  9.  AfxMessageBox("test server 1" );
  10.  Serv->Create(GetDocument()->Port);
  11.  AfxMessageBox("test server 2" );
  12.  Serv->Listen();
  13.  Sock = new CTableauBlancSocket(this);
  14.  Serv->Accept(*Sock);
  15.  AfxMessageBox("Connexion acceptée" );
  16. }
  17. else
  18. {
  19.  // mode client
  20.  Sock = new CTableauBlancSocket(this);
  21.  AfxMessageBox("test client 1" );
  22.  Sock->Create();
  23.  AfxMessageBox("test client 2" );
  24.  Sock->Connect(GetDocument()->AdresseIp,GetDocument()->Port);
  25.  AfxMessageBox("Connexion Etablie" );
  26.  //Sock.Connect(Serveur,Port);
  27.  BConnecte=true;
  28.  //CSocketFile file(&Sock);
  29.  //CArchive arOut(&file,CArchive::store);
  30. }
  31. }


 
 
J'ai cette erreur quand il passe à la ligne: Sock = new CTableauBlancSocket(this);
Exception non gérée à 0x7c239eea (mfc71d.dll) dans Tableau Blanc.exe:0xC0000005: Violation d'accès lors de la lecture de l'emplacement 0x00000020.
 
Le déboggueur pointe cette ligne ASSERT(::IsWindow(m_hWnd) || (m_pCtrlSite != NULL)); de winocc.cpp. Je comprend pas bien pourquoi ca bloque ici.  
Ma classe View héritant de CScrollView lui convient pas ?
 
 
Merci d'avance de votre aide :jap:
Si c'est pas clair, je suis évidemment là  :bounce:


Message édité par Pwill le 31-03-2005 à 19:30:28
mood
Publicité
Posté le 28-03-2005 à 16:47:52  profilanswer
 

n°1027450
Harkonnen
Modérateur
Un modo pour les bannir tous
Posté le 28-03-2005 à 17:39:30  profilanswer
 

dans la classe principale de ton appli, t'as lancé un AfxSocketInit() ?


---------------
J'ai un string dans l'array (Paris Hilton)
n°1027469
Pwill
Deux fois Né
Posté le 28-03-2005 à 17:53:53  profilanswer
 

Non pas du tout, je vais regarder de plus près cette fonction :jap:

n°1027478
Pwill
Deux fois Né
Posté le 28-03-2005 à 18:06:56  profilanswer
 

J'ai placé AfxSocketInit() dans le constructeur de la classe TableauBlancView. Ca ne change rien, l'appel de  

Code :
  1. Sock = new CTableauBlancSocket(this);

 
ne passe pas, avec la même erreur.
 
Hmm si j'avais oublié d'activer les Windows Socket à la création du projet... il se passerait quoi ?  
 
Sinon, j'ai repris le code de ma prof, mais elle partait d'une classe héritant d'un CDialog. Elle n'avait pas besoin de dessiner quoi que ce soit.
Donc sa classe socket elle a un membre de type CDialog (enfin de la classe qui en hérite).
 
L'erreur porte sur cette fonction de winocc.cpp

Code :
  1. BOOL CWnd::EnableWindow(BOOL bEnable)
  2. {
  3. ASSERT(::IsWindow(m_hWnd) || (m_pCtrlSite != NULL)); // ca passe pas
  4. if (m_pCtrlSite == NULL)
  5.  return ::EnableWindow(m_hWnd, bEnable);
  6. else
  7.  return m_pCtrlSite->EnableWindow(bEnable);
  8. }


 

n°1027498
Pwill
Deux fois Né
Posté le 28-03-2005 à 18:16:36  profilanswer
 

Je rectifie ce que j'ai dit, j'ai bien un AfxSocketInit(), par défaut il est ainsi:
 

Code :
  1. BOOL CTableauBlancApp::InitInstance()
  2. {
  3. // InitCommonControls() est requis sur Windows XP si le manifeste de l'application
  4. // spécifie l'utilisation de ComCtl32.dll version 6 ou ultérieure pour activer
  5. // les styles visuels.  Dans le cas contraire, la création de fenêtres échouera.
  6. InitCommonControls();
  7. CWinApp::InitInstance();
  8. if (!AfxSocketInit())
  9. {
  10.  AfxMessageBox(IDP_SOCKETS_INIT_FAILED);
  11.  return FALSE;
  12. }
  13.         ...
  14. }


 
 

n°1028272
Pwill
Deux fois Né
Posté le 29-03-2005 à 13:36:51  profilanswer
 

La violation d'accès n'est-elle pas liée au paramètre passé au constructeur ?
 
Sock = new CTableauBlancSocket(this);
 
this est un pointeur TableauBlancView  
C'est la classe de base quand on crée un projet application MFC. (avec biduleDoc)

n°1028513
Pwill
Deux fois Né
Posté le 29-03-2005 à 15:52:23  profilanswer
 

Je ne sais pas précisément pourquoi mais je ne peux pas utiliser une instance de la classe de type MonProjetView (MonProjet = nom du projet, ici TableauBlanc, autrement dit c'est la classe qui gère l'affichage et l'intéracion avec l'utilisateur) dans ma classe TableauBlancSocket. Par contre avec une instance de MonProjetDoc, aucun problème à l'initialisation du socket :??:
 
Si quelqu'un voit ce que je veux dire, et pourrait m'expliquer pourquoi, je dis pas non. :jap:

n°1031526
Pwill
Deux fois Né
Posté le 31-03-2005 à 17:49:12  profilanswer
 

Nouveau problème:  
Violation d'accès en lecture à la ligne 10...

Code :
  1. void CTableauBlancDoc::ProcessPendingRead(void)
  2. {
  3. // if (!BConnecte) return;
  4. TRY
  5. {
  6.  AfxMessageBox("dans le try" );
  7.  CDessin* d;
  8.  d= new CCarre;
  9.  AfxMessageBox("Apres carre" );
  10.  if (! Pt_arIn->IsBufferEmpty()) // ici violation d'accès en lecture
  11.   d->Serialize(*Pt_arIn);
  12.  AfxMessageBox("Serialize ok" );
  13.  Elements.Add(d);
  14.  UpdateAllViews(NULL);
  15. }
  16. CATCH (CFileException, e) // ne marche pas avec CArchiveException....
  17. {
  18.  if (Serv!=NULL)
  19.  {
  20.   Serv->Close();
  21.   delete Serv;
  22.   Serv = NULL;
  23.  }
  24.  AfxMessageBox("Connexion perdue" );
  25.  BConnecte = false;
  26. }
  27. END_CATCH
  28. }


 
Déclaré ainsi:

Code :
  1. class CTableauBlancDoc : public CDocument
  2. {
  3. [...]
  4. public :
  5. [...]
  6. CTableauBlancSocket *Serv;
  7. CTableauBlancSocket *Sock;
  8. CSocketFile *Pt_file;
  9. CArchive *Pt_arIn;
  10. CArchive *Pt_arOut;
  11. };


 
Ca fait plus de 2 heures que je revois mon code, fais des tests, sans trop savoir où chercher. Impossible de sérialiser à partir de cette archive.
Pourtant je crois avoir réussi à sérialiser dans Pt_arOut (à partir d'une classe héritant de CScrollView).
 
Pourquoi là je ne peux pas sérialiser dans cette archive à partir de la classe même (CDocument) ou elle est déclarée ??
 
Encore une fois si je ne suis pas clair ou s'il vous manque des bouts de code, je suis là pour un moment  :sarcastic:
Merci de bien vouloir me donner des pistes de recherche  :(


Message édité par Pwill le 31-03-2005 à 18:38:25
n°1031830
IrmatDen
Posté le 31-03-2005 à 22:02:57  profilanswer
 

tu devrais peut-être essayer ça :

Code :
  1. if (Pt_arIn && (! Pt_arIn->IsBufferEmpty()))

n°1032519
Pwill
Deux fois Né
Posté le 01-04-2005 à 15:14:18  profilanswer
 

Je te remercie pour ton attention ;)
 
Ben en fait ca change rien, j'ai toujours la même erreur.
En fait, je viens de remarquer que dans cette fonction il ne faut pas que j'évalue la moindre variable de la classe CTableauBlanc (CDocument) sinon... exception non gérée, violation d'accès en lecture blabla.
 
Pour info, ProcessPendingRead(void) est appelée dans ma classe socket de cette manière:
 

Code :
  1. // TableauBlancSocket.h
  2. #pragma once
  3. class CTableauBlancDoc;
  4. // Cible de la commande CTableauBlancSocket
  5. class CTableauBlancSocket : public CSocket
  6. {
  7. public:
  8. CTableauBlancSocket();
  9. CTableauBlancSocket(CTableauBlancDoc* p);
  10. virtual ~CTableauBlancSocket();
  11. virtual void OnReceive(int nErrorCode);
  12. virtual void OnClose(int nErrorCode);
  13. CTableauBlancDoc* m_Doc;
  14. };
  15. // TableauBlancSocket.cpp
  16. #include "stdafx.h"
  17. #include "Tableau Blanc.h"
  18. #include "TableauBlancSocket.h"
  19. #include ".\tableaublancsocket.h"
  20. #include "Tableau BlancDoc.h"
  21. CTableauBlancSocket::CTableauBlancSocket()
  22. {
  23. m_Doc=NULL;
  24. }
  25. CTableauBlancSocket::CTableauBlancSocket(CTableauBlancDoc* p)
  26. {
  27. m_Doc=p;
  28. }
  29. CTableauBlancSocket::~CTableauBlancSocket()
  30. {
  31. }
  32. // Fonctions membres CTableauBlancSocket
  33. void CTableauBlancSocket::OnReceive(int nErrorCode)
  34. {
  35. // TODO : ajoutez ici votre code spécialisé et/ou l'appel de la classe de base
  36. if (m_Doc=NULL) return;
  37. m_Doc->ProcessPendingRead();
  38. CSocket::OnReceive(nErrorCode);
  39. }
  40. void CTableauBlancSocket::OnClose(int nErrorCode)
  41. {
  42. // TODO : ajoutez ici votre code spécialisé et/ou l'appel de la classe de base
  43. if (m_Doc==NULL) return;
  44. m_Doc->ProcessPendingClose();
  45. CSocket::OnClose(nErrorCode);
  46. }


Message édité par Pwill le 01-04-2005 à 15:16:49
mood
Publicité
Posté le 01-04-2005 à 15:14:18  profilanswer
 

n°1032771
IrmatDen
Posté le 01-04-2005 à 20:14:25  profilanswer
 

Pour la suggestion c'est souvent une base d'erreur donc c'était pour ça la petite suggestion ...
et comment est créé et initialisé Pt_arIn ?

n°1033123
Pwill
Deux fois Né
Posté le 02-04-2005 à 15:08:16  profilanswer
 

Code :
  1. void CTableauBlancDoc::Connecte(void)
  2. {
  3. if(ModeAppli)
  4. {
  5.  //mode serveur
  6.  Serv = new CTableauBlancSocket(this);
  7.  if(Serv->Create(Port))
  8.   Serv->Listen();
  9.  else AfxMessageBox(" Socket serv pb create" );
  10.  Sock = new CTableauBlancSocket(this);
  11.  if(Serv->Accept(*Sock))
  12.   AfxMessageBox("Connexion acceptée" );
  13.  else AfxMessageBox("Connexion refusée" );
  14.  Pt_file  = new CSocketFile(Sock);
  15.  Pt_arOut = new CArchive(Pt_file,CArchive::store);
  16.  Pt_arIn  = new CArchive(Pt_file,CArchive::load);
  17. }
  18. else
  19. {
  20.  // mode client
  21.  Sock = new CTableauBlancSocket(this);
  22.  if (Sock->Create()) AfxMessageBox("Create ok" );
  23.  if(Sock->Connect(AdresseIp,Port)) AfxMessageBox("Connect ok" );
  24.  AfxMessageBox("Connexion établie" );
  25.  Pt_file  = new CSocketFile(Sock);
  26.  Pt_arOut = new CArchive(Pt_file,CArchive::store);
  27.  Pt_arIn  = new CArchive(Pt_file,CArchive::load);
  28. }
  29. BConnecte=true;
  30. }


 
Voila la série d'initialisations.
Ca marche assez bien puisque je peux me connecter et me déconnecter à volonté.
Le problème c'est que dans la fonction CTableauBlancDoc::ProcessPendingRead(void) je peux même pas faire de if sur ma variable BConnecte. Si je fais (seulement) un AfxMessageBox("bla" ); dans la foncion ca passe.  
Un simple et unique AfxMessageBox(BConnecte) me sort l'erreur de violation d'acces.
:??:

n°1033128
hust
Posté le 02-04-2005 à 15:21:39  profilanswer
 

Dans ta fonction :

Code :
  1. void CTableauBlancSocket::OnReceive(int nErrorCode)
  2. {
  3.     // TODO : ajoutez ici votre code spécialisé et/ou l'appel de la classe de base
  4.     if (m_View=NULL) return;
  5.     m_View->ProcessPendingRead();
  6.     CSocket::OnReceive(nErrorCode);
  7. }


 
ton if contient une erreur : m_View == NULL :o

n°1033132
Pwill
Deux fois Né
Posté le 02-04-2005 à 15:36:24  profilanswer
 

:fou: Oh punaise la boulette  :pfff:  :fou:  
Une après midi de perdue et quelques heures  [:morpheusbx]  
La fonction du dessous je ne fais pas l'erreur et suis même pas capable de penser à cette boulette ou faire la comparaison  :cry:  
 
Eh ben voila qui explique tout, ca m'a même pas traversé l'esprit tellement je pensais que je gérais mal mes sockets, sérialisations, etc.
 
:jap: Ben merci !  
Bon binôme qui ne s'est jamais plongé dans le projet n'a rien vu non plus, pourtant ca aurait pu le marquer une telle bétise  :whistle:  
 
Merci à vous deux ! ;)


Message édité par Pwill le 02-04-2005 à 15:39:55
n°1033133
hust
Posté le 02-04-2005 à 15:43:39  profilanswer
 

Pour éviter ce genre d'erreur par la suite, tu peux mettre
 
if( NULL == m_View )
 
ton compilo te préviendra en cas d'erreur ;)

n°1033134
WhatDe
Posté le 02-04-2005 à 15:45:32  profilanswer
 

hust a écrit :

Pour éviter ce genre d'erreur par la suite, tu peux mettre
 
if( NULL == m_View )
 
ton compilo te préviendra en cas d'erreur ;)


Vraiment pas lisible en tout cas.


---------------
[:whatde]
n°1033135
hust
Posté le 02-04-2005 à 15:47:48  profilanswer
 

Question d'habitude je pense :o

n°1033141
Pwill
Deux fois Né
Posté le 02-04-2005 à 16:04:09  profilanswer
 

Oui surement une question d'habitude. Je fais jamais l'erreur de test avec =, suffit que je la fasse dans un projet pour qu'après ca ne me titille même pas l'esprit.
Une violation d'accès ca aurait du me faire tilt que j'avais moi-même mis le truc à null.


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  [MFC] Violation d'accès en lecture ? pourquoi ?

 

Sujets relatifs
Acces et les champs rajouté dans une tableLecture d'un fichier texte contenu dans un JAR
Lecture d'un texte dans un DXF[MFC] Problème avec OnPaint et un Timer
acces a la DB et mise a jour sur plusieurs tablesviolation d'acces avec fclose et delete
:hello: Dessinez c'est gagnez en C++ / MFC[Visual C++ - MFC] DLL et Notification d'événements (OnAccept)
MFC Problème d'affichage (OnPaint() et ON_WM_PAINT()) 
Plus de sujets relatifs à : [MFC] Violation d'accès en lecture ? pourquoi ?


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR