简体   繁体   English

如何修复 C++ 中的“分段错误”错误

[英]How to fix 'Segmentation fault' error in c++

I'm trying to learn how to use the gdb debugger to fix this sample code.我正在尝试学习如何使用 gdb 调试器来修复此示例代码。 When stepping through the debugger, I can see that the line 'mylist[i]->val = i;'单步调试调试器时,我可以看到“mylist[i]->val = i;”这一行is throwing the segmentation fault.正在抛出分段错误。

I think I understand what a segmentation fault is, but I don't understand how this line could be causing it.我想我明白什么是分段错误,但我不明白这条线是如何导致它的。 Do I need to allocate memory for the mylist vector?我需要为 mylist 向量分配内存吗? How would I do that?我该怎么做? I thought that the vector was already initialized and ready in main(), but I'm not really sure.我认为向量已经在 main() 中初始化并准备好了,但我不太确定。

I have tried using 'new' for each node in the mylist vector but that gave me a compile error.我曾尝试对 mylist 向量中的每个节点使用“new”,但这给了我一个编译错误。

node* mylist[i] = new node; //what I tried
mylist[i]->val = i; 
mylist[i]->next = NULL;   

//error message
error: array must be initialized with a brace-enclosed initializer
node* mylist[i] = new node;

My code我的代码

class node
{
public:
    int val;
    node* next;
};

void create_LL(vector<node*>& mylist, int node_num)
{
    mylist.assign(node_num, NULL);

//create a set of nodes
    for (int i = 0; i < node_num; i++)
    {
        mylist[i]->val = i; //error happens here
        mylist[i]->next = NULL;
    }

... (relevant section of main() below)

int main(int argc, char ** argv)
{
    const int NODE_NUM = 3;
    vector<node*> mylist;
    create_LL(mylist, NODE_NUM);

The actual error shown is "Segmentation fault (core dumped)"显示的实际错误是“分段错误(核心转储)”

When I print mylist right before the error line it shows当我在错误行之前打印 mylist 时,它显示

$1 = std::vector of length 3, capacity 3 = {0x0, 0x0, 0x0}

I am still learning c++ so I might be missing something really basic.我仍在学习 C++,所以我可能会遗漏一些非常基本的东西。 I would really appreciate any help.我真的很感激任何帮助。 Thanks!谢谢!

For starters, it's better if you hide variables inside a class .对于初学者来说,最好将变量隐藏在class If you're not going to, the convention is to use a struct .如果你不打算,约定是使用struct It's also good practice to provide some constructor in that case, and maybe with default values:在这种情况下提供一些构造函数也是一种很好的做法,并且可能具有默认值:

class node
{
    int val;
    node* next;
public:
    node(int v= 0, node* n= nullptr) : val(v), next(n) {}
};

Note the use of nullptr instead of NULL .请注意使用nullptr而不是NULL Using the latter is a bad practice in c++.在 C++ 中使用后者是一种不好的做法。

The problem is that you can't use positions on a std::vector if they have not been allocated.问题在于,如果尚未分配位置,则无法使用std::vector上的位置。 When you do mylist[i]->val = i;当你做mylist[i]->val = i; you're in the lands of undefined behaviour.你处于未定义行为的领域。

You need first to push_back() or emplace_back() into a std::vector .您首先需要将push_back()emplace_back()放入std::vector So it's size() grows as it puts your data at the end (the back ) of the vector .所以它的size()增长,因为它将您的数据放在vector的末尾( back )。 You could also use other methods, like reserve() .您还可以使用其他方法,例如reserve() While push_back() pushes node* elements on your list, emplace_back() would construct them in place with no copy (no difference with raw pointers, but you can use a vector<node> instead of vector<node*> which is more straightforward.虽然push_back()node*元素推送到您的列表中,但emplace_back()会在没有副本的情况下构建它们(与原始指针没有区别,但您可以使用vector<node>而不是vector<node*> ,这更直接.

// create a set of nodes
void create_LL(vector<node>& mylist, int node_num)
{
    for (int i = 0; i < node_num; i++) {
        mylist.emplace_back(i, nullptr); // calls node::node(i, nullptr) and inserts it at the end of the vector
    }

or或者

// create a set of nodes
void create_LL(vector<node*>& mylist, int node_num)
{
    for (int i = 0; i < node_num; i++) {
        mylist.emplace_back(new node(i, nullptr));
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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