2012-06-08 5 views
1

Работа в списке смежности -> направленный взвешенный графC++ список смежности указателей и структур

Один класс выглядит следующим образом, то есть заголовок:

class CGraph; 
class CMap { 
public: 
    //voided constructors and destructors 
    //functions one is: 
    void SetDirGraph(string commands); 

private: 
    CGraph* m_myMap; 
}; 

Второй класс:

class CNode { 
public: 
    //voided constructor and desctructor 
    int m_distance, m_vert; 
    bool m_isKnown; 
}; 

typedef struct edges { 
    int v2, weight; 
} edge; 

class CGraph { 
public: 
    CGraph(int map_size); 
    ~CGraph(void); 

    void AddMap(int v1, int v2, int weight); 
    void AddEndVert(int v2, int weight); 

private: 
    list<edge> List; 
    int size; 

public: 
    CNode* verts; 
}; 

Я читаю вершины из файла, и это работает. Моя проблема заключается в том, что мне трудно создать список смежности на основе приведенного кода. Сначала я пытаюсь использовать указатели, указывающие на список, и он работает неправильно. Я не знаю, как создать мои указатели в списке, не написав над ними.

void CMap::SetDirGraph(string command) { 
    istringstream buffer(command) 
    char ch; 
    int num, vert1, vert2, weight; //specify vertices and weight and number of vertices 

    buffer>>ch; //throw away first character (not needed) 
    buffer>>num // size of vertices 

    while(!buffer.eof()) { // keep reading until end of line 
     buffer>>v1;   // vertex start 
     buffer>>v2;   // vertex end 
     buffer>>weight; 

     m_myMap = new CGraph(map_size); //initialize m_myMap. 
     m_myMap->verts->m_vert = v1; // mymap->verts->vert points to first edge 
     m_myMap->AddMap(v1, v2, weight); // create list? 
     m_myMap->AddEndVert(v2, weight); //create list? push v2 and weight on my list using my list. 
    } 
} 

Я пробовал несколько разных способов, и я все время путаю себя, любая точка в правильном направлении была бы удивительной.

EDIT: У меня есть еще один код, если необходимо, чтобы создать, просто публикуя основной материал. Что я подразумеваю под «нерабочим», так это то, что я просто пишу поверх предыдущей вершины. Я не знаю, должен ли я создать массив, используя m_myMap (попробовал и все еще записывает и также получает ошибку памяти). Ошибок компилятора нет.

+0

«не работает» - пожалуйста, напишите более подробно. Что не работает и какая отладка вы сделали? –

+0

отредактирован, на самом деле просто смущен тем, как я работаю над своими указателями, чтобы не переопределять мои предыдущие данные. –

ответ

1

Я не знаю, как создать указатели на список, не набирая их.

Помимо вашего заявления, ответ на этот вопрос является оператором new, который, как я полагаю, вам известен, поскольку вы использовали его в своем примере кода. Код, подобный int * a = new int(42);, выделяет память для int на кучу, и вы несете ответственность за очистку, когда она больше не нужна. Таким образом, вы получаете полный контроль над тем, как долго будет доступна переменная. В int x = 42; int * a = &x;, с другой стороны, x будет автоматически очищаться, когда закончится область действия, а a будет указателем на блок памяти, в котором больше нет значимых данных. Если вы попытаетесь разыменовать его, вы столкнетесь с неопределенным поведением, и, если вам повезет, ваша программа взорвется.

Если вы можете использовать стандарт C++ 11 или библиотеку, предлагающую интеллектуальные указатели, вы должны, по возможности, лучше управлять указателем. Умный указатель - это объект, который содержит выделенную память и автоматически освобождает его при его разрушении. Более конкретная информация сильно зависит от того, какой тип интеллектуального указателя вы используете. Причиной использования интеллектуальных указателей является то, что управление самим является утомительным и подверженным ошибкам. Если вы не указали delete указатели, которые вы выделили, ваше приложение будет продолжать выделять больше памяти, пока оно не взорвется в какой-то день (в зависимости от того, как часто и сколько памяти вы выделяете); это называется утечкой. Если вы вызываете delete несколько раз, ваша программа также выйдет из строя. Вот пример 11 shared_ptr C++ в приложении:

class CMap 
{ 
    private: 
    std::shared_ptr<CGraph> m_myMap; 
    // etc. 
}; 

// in SetDirGraph 
m_myMap.reset(   // if the smart pointer has previously been managing 
         // memory, it will free it before allocating new 
    new CGraph(map_size) // allocate CGraph as before 
); 

Кроме того, то, что мы надеемся, отвечает на ваш вопрос, я столкнулся с несколькими потенциальными проблемами в отношении кода:

  • Определенно неправильный: В SetDirGraph вы установили m_myMap->verts->m_vert = v1. m_myMap->verts - указатель.Вы только что создали m_myMap, и поэтому verts не инициализирован, следовательно, указывая на случайный блок памяти. Затем вы пытаетесь разыменовать его на m_myMap->verts->m_vert = v1. Это не сработает. Сначала необходимо создать verts, то есть verts = new CNode;.

  • typedef struct edges { /* etc */ } edge; является конструкцией C и нет необходимости в обертке typedef на C++. Это действительно работает и все, но это действительно избыточно, и многие из этих конструкций просто загрязняют пространство имен, в котором вы работаете.

  • Вам действительно нужны указатели в первую очередь? Ваши предоставленные фрагменты не подсказывают, зачем вам их использовать. Вы должны уменьшить использование указателей до минимума (или, по крайней мере, использовать интеллектуальные указатели, см. Выше)

+0

Спасибо, я был полной Думбой **. Я пытался создать график не в том месте. Я закончил тем, что создал указатель на свой список из AddMap и AddEndVert. Благодарю за помощь. Некоторые из таких вещей, как typedef, были написаны не мной, а кем-то другим. Но еще раз спасибо! –