multithreading - Pointer is deallocated shortly after declaration in multithread function -


i'm having weird problem in code of mine. variable seems fine after declaration corrupted right after , results in access violation (basically pointer still pointing @ same place memory seems unallocated). i'm pretty sure problem related multithreading have no idea since quite new multithreading.

here code :

#include "firewall.h" #include <ws2tcpip.h>  firewall::firewall(void) { }   firewall::~firewall(void) { }  void firewall::parsefile(string filepath) {     xmlnode xmainnode=xmlnode::openfilehelper(filepath.c_str(),"firewall");      // filtrage     xmlnode nodefiltrage = xmainnode.getchildnode("filtrage");     xmlnode currentnode;      for(int i=0; < nodefiltrage.nchildnode();i++)     {         currentnode = nodefiltrage.getchildnode(i);          string nom = currentnode.getname();          if(nom == "permettre")             mapfiltrage_.insert(pair<int,bool>(atoi(currentnode.getattribute().lpszvalue), true));          else if(nom == "bloquer")             mapfiltrage_.insert(pair<int,bool>(atoi(currentnode.getattribute().lpszvalue), false));     }      // redirection      xmlnode noderedirection = xmainnode.getchildnode("redirection");     xmlnode currentsubnode;      for(int = 0; < noderedirection.nchildnode(); i++)     {         currentnode = noderedirection.getchildnode(i);         currentsubnode = currentnode.getchildnode("source");          sourcedestination source((string)currentsubnode.getattribute("adresse"), atoi(currentsubnode.getattribute("port")));          currentsubnode = currentnode.getchildnode("destination");         sourcedestination destination((string)currentsubnode.getattribute("adresse"), atoi(currentsubnode.getattribute("port")));          mapredirection_.insert(pair<sourcedestination, sourcedestination>(source,destination));           pair<sourcedestination, sourcedestination> test;     }   }  void firewall::initialiser() {     std::map<int, bool>::iterator iterfiltrage = mapfiltrage_.begin();     handle handlethread;      std::string tempfiltrage = "localhost";     thread_arg arg;      // parcours et lancement des connexions de filtrage     while(iterfiltrage != mapfiltrage_.end())     {         arg.port = (*iterfiltrage).first;         arg.host = tempfiltrage;         arg.objref = this;          handlethread = createthread(null, 0, listenthread, &arg, 0, null);         listethread_.push_back(handlethread);          iterfiltrage++;     }      // parcours et lancement des connexions de redirection     std::map<sourcedestination, sourcedestination>::iterator iterredirection = mapredirection_.begin();      while(iterredirection != mapredirection_.end())     {         // Éviter la duplication inutile des sockets         if(mapfiltrage_.find((*iterredirection).first.port()) == mapfiltrage_.end())         {             arg.host =  (*iterredirection).first.host();             arg.port = (*iterredirection).first.port();             arg.objref = this;              handlethread = createthread(null, 0, listenthread, &arg, 0, null);             listethread_.push_back(handlethread);         }          iterredirection++;     } }   dword winapi firewall::listenthread(lpvoid lpparam) {     thread_arg* temp = (thread_arg*)lpparam;     firewall* firewallref = temp->objref;      return firewallref->runthread(lpparam); }  dword firewall::runthread( lpvoid lpparam ) {     thread_arg* infossocket = (thread_arg*)lpparam;      // créer le socket et l'attacher à la source     socket sock = socket(af_inet, sock_stream, 0);      if(sock == invalid_socket)     {         cout << "erreur de creation de socket" << endl;         return exit_failure;     }      //recuperation de l'adresse locale     hostent *thishost;     const char* test = infossocket->host.c_str();     thishost=gethostbyname(test);     char* ip;     ip=inet_ntoa(*(struct in_addr*) *thishost->h_addr_list);      sockaddr_in sin;     sin.sin_addr.s_addr = inet_addr(ip);     sin.sin_family = af_inet;     sin.sin_port = htons(infossocket->port);        if(bind(sock, (sockaddr*)&sin, sizeof(sin)) == socket_error)     {         cout << "erreur de binding" << endl;         return exit_failure;     }      // contexte du client     sockaddr_in csin;     socket csock;     socklen_t crecsize = sizeof(csin);      listesocket_.push_back(sock);     listesocket_.push_back(csock);      // Écouter sur le port     if(listen(sock, 5) == socket_error)     {         cout << "erreur de listen" << endl;         return exit_failure;     }      //csock = accept(sock, (sockaddr*)&csin, &crecsize);      return exit_success; }  void firewall::quitter() {     // fermer les sockets     vector<socket>::iterator iter1 = listesocket_.begin();      while(iter1 != listesocket_.end())     {         closesocket((*iter1));         iter1++;     }      // fermer les threads      vector<handle>::iterator iter2 = listethread_.begin();      while(iter2 != listethread_.end())     {         terminatethread((*iter2), exit_success);         closehandle((*iter2));     } } 

thanks lot.

your problem in code:

thread_arg arg;  loop(...) {     arg = ...;     handlethread = createthread(..., &arg, ...); } 

every thread started here receives address of same thread_arg instance. then, starting next thread, again modify instance under feet of started thread. remedy, create structure holds necessary arguments (host, port, this) , handle thread. store structure in std::list , pass address of according element createthread().

there problem in code, should check returnvalues. it's nicer ask on code if know obvious errors have been detected. that, it's easiest use exceptions. after createthread(), should possibly beginthread() instead, add these lines:

if(handlethread == null)     throw std::runtime_error("createthread() failed"); 

in second step, create dedicated exception class, derived runtime_error, holds win32 error code (see getlasterror()) , includes textual error description in exception message (see formatstring()). might sound lot of code nothing, write once , can reuse in many places.

lastly, quitter() has 2 problems. first infinite loop. assuming don't need handles after closing them, try instead:

for(; listethread_.empty(); listetread_.pop_back()) {     terminatethread(listethread_.back(), exit_success);     closehandle(listethread_.back()); } 

you can write while-loop, too, prefer for-loop if number of iterations fixed. of course, still need check returnvalues of terminatethread() , closehandle(). second issue terminatethread() bad idea, because might terminating thread in middle of remains half-done. search web "terminatethread harmful". @ point here, can wait end using waitforsingleobject().


Comments

Popular posts from this blog

android - getbluetoothservice() called with no bluetoothmanagercallback -

sql - ASP.NET SqlDataSource, like on SelectCommand -

ios - Undefined symbols for architecture armv7: "_OBJC_CLASS_$_SSZipArchive" -