Boost logo

Boost Users :

From: Tom Lenaerts (tlenaert_at_[hidden])
Date: 2006-09-19 04:39:35


Hi stephan,

sorry about the lack of detail in my question.
Below you can find the code for a network factory class. The code
reads a file (like this)

300
0 37 0 1 2 3 4 5 6 8 9 15 17 21 42 44 51 56 63 66 77 84 86 93 123
126 128 129 151 153 163 164 170 219 225 240 247 261 288 290
1 12 0 0 2 11 18 33 47 66 95 127 192 209 211
2 51 0 1 0 3 5 6 7 8 10 12 13 14 15 16 17 19 25 27 31 35 36 38 49
78 79 81 84 88 91 93 104 111 139 156 169 175 178 188 203 208 223 227
243 247 249 253 255 266 267 268 282 286
3 8 0 2 0 4 29 42 55 62 257
4 11 0 3 0 18 34 52 59 108 139 216 235 296
5 14 0 2 0 26 50 56 58 71 74 80 186 191 193 194 283
6 14 0 0 2 7 16 30 34 46 57 101 141 174 198 215 291
7 6 0 2 6 67 82 97 181
...

and when the member function 'create' is called, the network should
be returned.

The error was a runtime error. I got the following answer from Xcode:

[Session started at 2006-09-19 09:57:00 +0200.]
#seed.in not found. Creating a new seed...
seed = 583597

gamenetwork has exited due to signal 10 (SIGBUS).

I examined your code and adapted mine to yours and noticed that the
error disappears
when I change

                                g=new Graph();

to

                                g=new Graph(1);

in the member function parseFile. It seems that this is the error
that I made (as I expected it is a silly one). Could you tell me why
the '1' is required here?

Thanks for the help

Tom

==networkfact.h

#ifndef __NETWORKFACTORY_H
#define __NETWORKFACTORY_H

#include "factory.h"
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graph_traits.hpp>

using namespace std;

typedef boost::adjacency_list<boost::vecS, boost::vecS,
boost::undirectedS> Graph;
typedef Graph* Graphptr;
typedef boost::graph_traits<Graph>::edge_descriptor Edge;
typedef boost::graph_traits<Graph>::vertex_descriptor Vertex;
typedef boost::graph_traits<Graph>::vertex_iterator Vertex_iterator;
typedef boost::graph_traits<Graph>::edge_iterator Edge_iterator;
typedef boost::graph_traits<Graph>::vertices_size_type Vertex_type;
typedef boost::property_map<Graph, boost::vertex_index_t>::type
IndexMap;

typedef Factory<Graph> GraphFactory; // the factory creates new graph
instances

class NetworkFactory: public GraphFactory {
        public:
                NetworkFactory(string fname): _fname(fname){}; //the file contains
a grpah specification.
                ~NetworkFactory(){};
                Graphptr create();
        private:
                Graphptr parseFile(istream&);
                void tokenize(const string&, vector<string>&, const string&
delimiters = " ");
                void processTokens(vector<string>&, Graphptr);
                string _fname;
};

typedef NetworkFactory* NetworkFactoryptr;
#endif

==networkfact.cpp

#include "networkfact.h"
#include <boost/lexical_cast.hpp>
#include <sstream>
#include <fstream>

Graphptr NetworkFactory::parseFile(istream& is){
        char c;
        int numnodes=0;
        Graphptr g=NULL;
        
        while(!is.eof()){
                c=is.get();
                if(c=='#' || c == '\n'|| c == ' '){
                        string line;
                        getline(is,line,'\n'); //ignore line content
                }
                else{ //it is not a comment line but useful information.
                        is.putback(c);
                        string line;
                        getline(is,line,'\n');
                        //start parsing the line
                        vector<string> tokens;
                        tokenize(line,tokens);
                        if(tokens.size() == 1){
                                numnodes= boost::lexical_cast<int>(tokens[0]);
                                g=new Graph(1);
                        }
                        else {
                                if(g!=NULL)
                                        processTokens(tokens,g);
                        }
                }
        }
        return g;
}

void NetworkFactory::tokenize(const string& str, vector<string>&
tokens, const string& delimiters){
     // Skip delimiters at beginning.
     string::size_type lastPos = str.find_first_not_of(delimiters, 0);
     // Find first "non-delimiter".
     string::size_type pos = str.find_first_of(delimiters, lastPos);

     while (string::npos != pos || string::npos != lastPos)
     {
         // Found a token, add it to the vector.
         tokens.push_back(str.substr(lastPos, pos - lastPos));
         // Skip delimiters. Note the "not_of"
         lastPos = str.find_first_not_of(delimiters, pos);
         // Find next "non-delimiter"
         pos = str.find_first_of(delimiters, lastPos);
     }
}

void NetworkFactory::processTokens(vector<string>& tokens, Graphptr g){
        if(tokens.size()>=3){
                int current = boost::lexical_cast<int>(tokens[0]);
                int numedges = boost::lexical_cast<int>(tokens[1]);
                Vertex first=boost::vertex(current,*g);
                for(int i=0;i<numedges;i++){
                        int other= boost::lexical_cast<int>(tokens[3+i]); //this has to be
3 because some other data is in position 2
                        Vertex second=boost::vertex(other,*g);
                        pair<Edge, bool> result=boost::edge(first,second,*g);
                        if(!result.second){
                                boost::add_edge(first,second,*g);
                        }
                }
        }
}

Graphptr NetworkFactory::create(){
        ifstream netwfile(_fname.c_str());
        if(netwfile.is_open()){
                Graphptr res= parseFile(netwfile);
                netwfile.close();
                return res;
        }
        return NULL;
}



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net