Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 12
  1. #1

    [C++] problema con iteratori

    Ciao a tutti!

    Avrei qualche problema con un programmino di questo tipo.

    In pratica avrei una lista di oggetti del tipo
    codice:
    list<Connection> connections;
    dove Connection è una classe da me creata, e che dovrei riempire.

    Poichè vorrei evitare i valori duplicati (non ho usato i set perchè questi mi forzano un ordinamento che non desidero) dovrei fare dei controlli all'atto dell'inserimento. In particolare vorrei una funzione che mi controlli se un oggetto è già presente nella lista "connections" sulla base di un mio criterio (basato sul confronto di una stringa).

    Una funzione dunque accetta due parametri: la lista che vorrei controllare e la stringa che funge da termine di paragone. Se esiste già un oggetto che contiene questa stringa in un suo attributo particolare la funzione dovrebbe restituirmi l'iteratore che punta all'oggetto in questione, altrimenti un riferimento alla fine della lista (connections.end()), che userò come termine di paragone per capire se l'elemento è presente o meno nella lista.

    Qualcosa del tipo...
    codice:
    list<Connection>::iterator Parser::connection_is_present(list<Connection> connections, string ip_src){ 
    	list<Connection>::iterator ret;
    	list<Connection>::iterator it;
    	//problema con la lista vuota
    	for (it = connections.begin(); it != connections.end(); ++it){
    		if ( it->ip_src == ip_src) return it;
    	}
    	return ret;
    }
    che poi richiamerò con...
    codice:
    list<Connection>::iterator conn_it = connection_is_present(connections, rules_it->getSrc());
    if ( conn_it  !=  connections.end()){
       ....
    }
    L'applicazione crasha inesorabilmente sulla if... dicendo "list iterators incompatible".
    Dove sto sbagliando ?

  2. #2
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    ret non è inizializzato e il compilatore non ha modo di sapere se appartiene alla list che gli passi come parametro oppure a un'altra lista.
    A ogni modo è inutile dal momento che it ( se non viene trovata nessuna corrispondenza) assumerà il valore .end() alla fine del ciclo.
    Dal momento che la list non viene modificata nella funzione, passala come reference, così risparmi il costruttore di copia.

    codice:
    list<Connection>::iterator Parser::connection_is_present(const list<Connection>&  connections, string ip_src){ 
    	list<Connection>::iterator it;
    	//problema con la lista vuota
    	for (it = connections.begin(); it != connections.end(); ++it){
    		if ( it->ip_src == ip_src) return it;
    	}
    	return it;
    }
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  3. #3
    innanzitutto grazie per la risposta!

    la variabile ret era il disperato tentativo di ovviare al problema che mi si poneva, oramai da diverse ore.

    Ho fatto come dici tu... ma adesso non compila dicendo
    " error C2679: '=' binario: non è stato trovato alcun operatore che accetti un operando destro di tipo 'std::list<_Ty>::_Const_iterator<_Secure_validatio n>'. È anche possibile che non vi siano conversioni accettabili.".

    Si riferisce all'inizializzazione nel ciclo for.

  4. #4
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Dimentico sempre i particolari.
    Se la list è const, lo deve essere anche l'iteratore, quindi:
    codice:
    list<Connection>::const_iterator Parser::connection_is_present(const list<Connection>&  connections, string ip_src){ 
    	list<Connection>::const_iterator it;
            // etc...
    In alternativa puoi usare la funzione find_if
    http://www.cplusplus.com/reference/algorithm/find_if/
    Ad esempio:

    codice:
    class IpSearch {
        public:
            IpSearch(const string& s) : s_(s) {}
            bool operator(Connection& s) { return (s.ip_src == s_); }
         private:
            string s_;
    };
    
    list<Connection>::iterator it = find_if(myList.begin(),myList.end(),IpSearch(ip_src));
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  5. #5
    Ho risolto con la prima soluzione che mi hai proposto.
    Ti ringrazio davvero tantissimo... ero a tribolare da ore e non ci sarei mai arrivato da solo!

    Potrei sapere il motivo per cui devo utilizzare const ?

  6. #6
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Non è strettamente necessario. E' solo un'informazione in più che si da al compilatore. Col const si afferma che l'oggetto passato come parametro non verrà modificato dal codice interno alla funzione. In pratica è come passare per valore l'oggetto, solo che passandolo per valore, viene richiamato il costruttore di copia (un passaggio non necessario); passandolo come const reference, no.
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  7. #7
    ora che ho dichiarato l'iteratore costante ottengo questo errore

    "impossibile convertire il puntatore 'this' da 'const Connection' a 'Connection &'"

    il pezzo di codice incriminato è questo
    codice:
    		if ( conn_it  ==  connections.end()){
    
    			Host* h = new Host(rules_it->getDst());
    			h->addService(rules_it->getPort()+"/"+rules_it->getProtocol());
    
    			Connection* c = new Connection(rules_it->getSrc());
    			c->addHost(*h);
    
    			connections.push_back(*c);
    		} else{
    			//la connessione è già presente..ho l'iteratore alla connessione trovata.
    			//devo vedere se devo aggiungere l'host o solo il servizio
                      list<Host>::const_iterator host_it = conn_it->host_is_present("aaa"); 
    			//if ()
    			
    		}
    il quale richiama una funzione simile alla precedente del tipo

    codice:
    list<Host>::const_iterator Connection::host_is_present(string ip_address){
    	list<Host>::const_iterator it;
    	for (it = this->hosts.begin(); it != this->hosts.end(); it++){
    		if (it->ip_address == ip_address) return it;
    	}
    	return it;

  8. #8
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Non hai capito. Il const_iterator si usa nel caso il parametro sia const, come qui.
    codice:
    list<Connection>::const_iterator Parser::connection_is_present(const list<Connection>&  connections, string ip_src){ 
    	list<Connection>::const_iterator it;
            // etc...
    Perché qui c'è un const list<Connection>&. Infatti nel primo codice che avevi postato non avevi di questi problemi perché avevi un list<Connection>

    Nel caso attuale non stai passando nessun oggetto const, quindi puoi usare il normale iteratore.
    codice:
    list<Host>::iterator Connection::host_is_present(string ip_address){
    	list<Host>::iterator it;
    	for (it = this->hosts.begin(); it != this->hosts.end(); it++){
    		if (it->ip_address == ip_address) return it;
    	}
    	return it;
    }
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  9. #9
    ho modificato come dici... ma il problema rimane esattamente lo stesso, e sembra essere quando provo a richiamare qualunque metodo di conn_it, es:

    conn_it->host_is_present("aaa");


    ti ringrazio infinitamente per l'aiuto...

  10. #10
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    A prima vista sembra che il const_iterator dia più problemi di quanti ne risolva.
    Occorrerebbe un pò di codice compilabile per dare una risposta più precisa, però intanto proverei a toglierlo.

    codice:
    list<Connection>::iterator Parser::connection_is_present(list<Connection>&  connections, string ip_src){ 
    	list<Connection>::iterator it;
    	//problema con la lista vuota
    	for (it = connections.begin(); it != connections.end(); ++it){
    		if ( it->ip_src == ip_src) return it;
    	}
    	return it;
    }
    Che poi cerca il tuo conn_it se non ho capito male. Nota che ho tolto il const, quindi l'oggetto è modificabile dalla funzione (che poi non lo faccia è un altro discorso), però risparmio comunque la chiamata al costruttore di copia; gli iteratori non sono più const_iterator, ma solo iterator.

    A parte questo noto altri errori nel codice: allocazioni dinamiche poi non liberi, tra l'altro inutili visto che poi passi l'oggetto derefenziato. A quel punto usalo come oggetto puro, non come puntatore.
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2026 vBulletin Solutions, Inc. All rights reserved.