c++结构中的列表

List inside struct in c++

本文关键字:列表 结构 c++      更新时间:2023-10-16

我在c++中有一个结构体中的列表;我只是想插入元素到这个列表,像往常一样。

我的结构是:

// A structure to represent an adjacency list node
struct AdjListNode
{
    int dest;
    int weight;
    std::list<int> adjacents;
    struct AdjListNode* next;
};
// A structure to represent an adjacency list
struct AdjList
{
    int pos;
    struct AdjListNode *head; // pointer to head node of list
};
// A structure to represent a graph. A graph is an array of adjacency lists.
// Size of array will be V (number of vertices in graph)
struct Graph
{
    int V;
    struct AdjList* array;
};
struct Graph* createGraph(int V)
{
    struct Graph* graph = (struct Graph*) malloc(sizeof(struct Graph));
    graph->V = V;
    // Create an array of adjacency lists. Size of array will be V
    graph->array = (struct AdjList*) malloc(V * sizeof(struct AdjList));

    // Initialize each adjacency list as empty by making head as NULL
    for (int i = 0; i < V; ++i) {
        graph->array[i].head = NULL;
    }
    return graph;
}

当我试图访问:

graph->array[position].head->adjacents->push_back(number);

它只是提示我:

进程结束,退出码139(被信号11:SIGSEGV中断)

对不起,我不知道这个错误。

分段故障来自

graph->array[position].head->adjacents.push_back(number);

graph->array[position].head = NULL;

我假设你的代码中有隐式结构不变量,因为你有两个可能连接的列表:从AdjList::head开始并迭代到AdjNode::next的链表和列表AdjNode::adjacent

为了保持连接,你可以添加一个(C风格的)函数,在两个列表中添加一个元素。

void
addAdjacent(AdjList& list, int adjacent) {
    // struct AdjListNode* newNode = (struct AdjListNode*) malloc(sizeof(struct AdjListNode));
    struct AdjListNode* newNode = new AdjListNode;
    newNode->next = list.head;
    list.head = newNode;
    newNode->dest = 0;
    newNode->weight = 0;
    newNode->adjacents = std::list<int>(); // undefined behavior with malloc
    newNode->adjacents.push_back(adjacent);
}

注意,将C风格(malloc/free)与c++风格(特别是与标准模板库的容器)混合是一个坏主意。我的代码的注释部分创建了一个分段错误,因为std::list没有用0填充其字段。

最后,下面的main函数即使有许多内存泄漏(参见valgrind工具)也能工作

int main(int argc, char** argv) {
   struct Graph* graph = createGraph(2);
   addAdjacent(graph->array[0], 1);
   addAdjacent(graph->array[1], 2);
   free(graph);
   return 0;
}

c++ -98的解决方案(没有任何内存泄漏)可以是:

// A structure to represent an adjacency list node
struct AdjListNode
{
    int dest;
    int weight;
    std::list<int> adjacents;
    struct AdjListNode* next;
    AdjListNode() : dest(0), weight(0), next(NULL) {}
};
// A structure to represent an adjacency list
struct AdjList
{
    int pos;
    struct AdjListNode *head; // pointer to head node of list
    // Initialize each adjacency list as empty by making head as NULL
    AdjList() : pos(0), head(NULL) {}
    ~AdjList()
      { while (head) {
          struct AdjListNode* temp = head;
          head = head->next;
          delete temp;
        }
      }
    void addAdjacent(int adjacent)
      { struct AdjListNode* newNode = new AdjListNode;
        newNode->next = head;
        head = newNode;
        newNode->adjacents.push_back(adjacent);
      }
};
// A structure to represent a graph. A graph is an array of adjacency lists.
// Size of array will be V (number of vertices in graph)
struct Graph
{
    int V;
    struct AdjList* array;
    // Create an array of adjacency lists. Size of array will be V
    Graph(int v) : V(v), array(NULL)
      { if (v >= 0 && v <= 1000)
          array = new struct AdjList[v];
        else
          throw std::bad_alloc();
      }
    ~Graph()
      { delete [] array; }
};
int main() {
   struct Graph* graph = new Graph(2);
   graph->array[0].addAdjacent(1);
   graph->array[1].addAdjacent(1);
   delete graph;
   return 0;
}