简体   繁体   中英

c++ segmentation fault when using vector to initialize linkedlist

i intends to initialize a linked-list using a vector

here is the code:

#include <vector>
#include <iostream>

using namespace std;

struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};

int main() {
    int n = 10;
    vector<ListNode> vecListNode;
    for (int i = 0; i != n; ++ i) {
        vecListNode.push_back(ListNode(i));
        if (i) {
            vecListNode[i-1].next = &vecListNode[i];
        }
    }
    ListNode *root = &vecListNode[0];
    while (root) {
        cout << root->val << endl;
        root = root->next;
    }
    return 0;
}

however, when i run this code, i get:

0

1

Segmentation fault: 11

i am using macintosh, default g++, thanks a lot

It is not safe to store the address of vector elements. References and iterators to vector elements are invalidated when you mutate the container (eg by inserting elements).

(You might make the code work by calling reserve() on the vector before you start, but it's still conceptually wrong. Presumably, the vector should store pointers to dynamically allocated list node objects, or perhaps some other form of indirection (eg a reference to the vector and an index).)

The vector automatically resizes on insert if there's not enough memory allocated yet. This operation invalidates the pointers to the elements because these are copied / moved to another memory location.

You might avoid this by reserving some space before inserting using the reserve() method of the vector.

Anyway, you shoul think of some other way to initialize your list.

Although I misunderstand what you are trying to achieve since you could just use an STL list. You can fix your code by storing ListNode pointers instead of instance. The following code will print correctly your list using the same alogrothm you did:

#include <vector>
#include <iostream>

using namespace std;

struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};

int main() {
int n = 10;
vector<ListNode*> vecListNode;
for (int i = 0; i != n; ++ i) {
    ListNode* pNode = new ListNode(i);
    vecListNode.push_back(pNode);
    if (i) {
        vecListNode[i-1]->next = vecListNode[i];
    }
}
ListNode *root = vecListNode[0];
while (root) {
    cout << root->val << endl;
    root = root->next;
}
return 0;
}

Then pointers are not invalidated since they are themselves stored in the vector. Note that the above program leaks. You'd need to free the memory used by the ListNode if you consider using it.

The output is then: [root@isl1 vectorList]# ./a.out

0

1

2

3

4

5

6

7

8

9

Enjoy!!!

Get a core dump and analyze it with the debugger of your choice. You can use ulimit -c unlimited to get core dumps and gdb to analyze them.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM