[QT c++] map probleem: segfault

Pagina: 1
Acties:

  • Shadowman
  • Registratie: Januari 2002
  • Niet online
Ik heb een chat-servertje gemaakt om te chatten. om de online users op te slaan heb ik hierbij gebruikt gemaakt van een map (de QMap van qt). logs van de server tot de segmetationfault (heb er zelf wat commentaar bij gezet in c++ stijl:
code:
1
2
3
4
5
6
7
8
9
10
Shadowman^T
9
0x40d1b6c8
Nieuwe naam: Shadowman3
Shadowman2^TShadowman3^T // verzonden naar Shadowman
Shadowman^TShadowman3^T   // verzonden naar Shadowman2
Shadowman^TShadowman2^T   // verzonden naar Shadowman3
verzend naar: Shadowman de mededeling dat er iemand is weggegaan: gebeurd
Shadowman2 is verdwenen (spoorloos)
map_read.erase(data)

^T is wat eigen code voor het chatprogramma die er op werkt.
en dit is het stukje code waar het soms fout gaat en soms ook niet.
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
void MyServerSocket::discardclient(void) {
  QSocket *gebruiker=(QSocket*)sender();
  user::Iterator data;
  for (data=map_read.begin(); data!=map_read.end(); data++) {
    if (data.data().return_socket()==gebruiker) {
      cout << data.data().gebruiker() << " is verdwenen (spoorloos)" << endl;
      map_read.erase(data);
      cout << "map_read.erase(data)" << endl;
//      break;
    }
    else {
      cout << "verzend naar: " << data.data().gebruiker() << " de mededeling dat er iemand is weggegaan";
      data.data().return_socket()->writeBlock("Er is iemand weggegaan\r\n", 25);
      cout << ": gebeurd" << endl;
    }
  }
  cout << "<online:>" << endl;
  for (user::Iterator online_users=map_read.begin(); online_users!=map_read.end(); ++online_users) {
    cout << online_users.data().gebruiker() << endl;
  }
  cout << "</online:>" << endl;
  for (user::Iterator data2=map_read.begin(); data2!=map_read.end(); ++data2) {
    cout << "naar de gebruiker: " << data2.data().gebruiker() << "wordt nu troep verzonden" << endl;
    users *verzenden=&data2.data();
    QString usernames="\x14";
    usernames.append(this->verzend_gebruikers(verzenden->return_socket()));
    usernames.append("\r\n");
    verzenden->return_socket()->writeBlock(usernames.ascii(), usernames.length());
    QString melding="Er is iemand verdwenen<BR>\r\n";
    verzenden->return_socket()->writeBlock(melding.ascii(), melding.length());
  }
//  delete gebruiker;
//  cout << "delete gebruiker" << endl;
}

en sorry dat het zo lang is maar ik kan niet exact aanwijzen waar het verkeerd gaat.

als het nog niet duidelijk is:
Ik wil de segmentation fault eruit en heb al vanalles geprobeerd om het eruit te krijgen maar ik kan de fout gewoon niet vinden. en wordt de data niet naar alle gebruikers verstuurd. en volgens mij gaat het bij de map_read.erase() fout.

* Shadowman hoopt dat het probleem duidelijk is

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 24-08 23:08
Al een debugger gebruikt? Dat wil wel eens helpen.

Leuk trouwens, dat het fout gaat bij het gebruik van een "map" object. Nu neem ik aan dat dit de standaard STL map is, en dat is een template klasse. Zonder instantie daarvan kan ik moeilijk zeggen of je de template goed gebruikt. Hoe is je map_read gedefinieerd?

[ Voor 4% gewijzigd door Soultaker op 17-01-2003 23:53 ]


  • Shadowman
  • Registratie: Januari 2002
  • Niet online
C++:
1
2
    typedef QMap<int,users> user;
    user map_read;

users is een aparte klasse waar de gegevens van de socket en de naam van de chatter wordt opgeslagen.
Zal hem nog door de debugger halen

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
Standaard fout:
code:
1
2
map_read.erase(data);
data++;
werkt niet, omdat data invalidated is na de erase.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 24-08 23:08
Mijn excuses, het probleem was dus wel zichtbaar zonder volledige typeinformatie. (Al kan het natuurlijk nooit kwaad om dat soort relevante informatie te vermelden). Overigens invalideert de erase() operator uitsluitend de iterator die je 'm meegeeft, dus het is niet moeilijk om een goede work-around te vinden, zonder elke keer opnieuw te zoeken of alle te verwijderen elementen op te slaan.