【问题标题】:Getting unknown Segmentation Fault "(address) in std::__cxx11::basic_string<char, std::char_traits<char>,..., std::allocator<char> > const&) const ()在 std::__cxx11::basic_string<char, std::char_traits<char>,..., std::allocator<char> > const&) const () 中获取未知分段错误“(地址)
【发布时间】:2019-12-02 21:09:15
【问题描述】:

我正在用 c++ 编写一个程序,它代表一个包含这些类和结构的论坛:

struct Date{            /* struct used to get a random day for each comment */
    int d,m,y,h,min;
    Date();
    void GetDate() const;
};

class Post{
  private:
    std::string Title;
    std::string Creator;
    std::string text;
    Date PostDate;
    int id;
  public:
    Post();
    ~Post();
    void postprint() const;
    int idprint();
    std::string get_creator() const; //returns the creator of the post
};

class Thread{
  private:
    std::string Subject;
    std::string Creator;
    Date ThreadDate;
    int post_nums = rand()%10+1;   // this will be the number of posts that will be made in the thread, used in threadprint()
    Post *posts = new Post[post_nums]; //so the randomizer doesn't return 0 array cells, max 10 posts for each thread
  public:
    Thread();
    ~Thread();
    std::string subjprint() const;
    void threadprint() const;
    int getnums() const; //returns the number of posts in the posts array
    Post *getposts() const; //returns to a pointer the array of posts
};

class Forum{
  private:
    std::string Title;
    Thread *threads = new Thread[3];
    //void printt(int) const;
  public:
    Forum(const std::string);
    ~Forum();
    void Print_threads() const;
    void Print_specified_thread(const std::string);
    Thread *Find_thread_subject(const std::string);
    void Print_specified_post(const int);
    Post *Find_specified_post(const int);
};

struct Post_list{
  Post *post;
  Post_list *next;
  Post_list *prev;
};

struct Tree_node{
  std::string Creator;
  Post_list *list_ptr;
  Tree_node *left;
  Tree_node *right;
};

class Thread_tree{
  private:
    Tree_node *node_root;
    void Tree_create(Tree_node *);
    int Tree_empty(Tree_node *);
    void Tree_sort(const Thread *, Tree_node *);
    void Tree_insert(const std::string, Tree_node *);
  public:
    Thread_tree(const Thread *);
};

现在我试图将每个线程的 cmets 的创建者放入一个 BST 中,将它们排序出来,其中每个节点 struct Tree_node 都有一个创建者字符串和他的 cmets 在一个列表中。class Thread_tree 的构造函数是什么像这样

Thread_tree::Thread_tree(const Thread *Thread1){  //constructor only to be called once
  cout << "Creating tree of post creators from thread " << Thread1->subjprint() << endl;
  Tree_create(this->node_root); //points root to NULL
  Tree_sort(Thread1, this->node_root);
}

Tree_sort()

void Thread_tree::Tree_sort(const Thread *Thread1, Tree_node *root){
  int k = Thread1->getnums(); //k is assigned to the number of the posts that the thread has
  Post *post_ptr = Thread1->getposts(); //ptr is assigned to the posts array of the thread
  for (int i=0; i<k; i++){
    cout << "\ni is " << i << endl;
    Tree_insert((post_ptr+i)->get_creator(), root);
  }
}

Tree_insert()

void Thread_tree::Tree_insert(const string creator, Tree_node *root){
  if (Tree_empty(root)){
    root = new Tree_node;
    root->Creator = creator;
    root->list_ptr = NULL;
    root->left = NULL;
    root->right = NULL;
  }
  else if (creator.compare(root->Creator) < 0){ //creator in string1 is smaller than the root->Creator
        Tree_insert(creator, (root->left));    // in ascending order

      }
   if (creator.compare(root->Creator) > 0) {//creator in string1 is bigger than the root->Creator
        Tree_insert(creator, (root->right));   //in ascending order
      }
}

在 main() 中,当我使用 'thread' 作为指向现有线程的指针创建树 Thread_tree Tree1(thread); 时,出现分段错误。我运行 gdb 调试器并在使用 bt 后收到此消息:

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7b7625a in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::compare(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const ()
   from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
(gdb) bt
#0  0x00007ffff7b7625a in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::compare(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const ()
   from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#1  0x00000000004025f1 in Thread_tree::Tree_insert (this=0x7fffffffe7c0, creator="user1234", root=0x1002) at classes.cpp:211
#2  0x00000000004026be in Thread_tree::Tree_insert (this=0x7fffffffe7c0, creator="user1234", root=0x604110) at classes.cpp:218
#3  0x00000000004024e4 in Thread_tree::Tree_sort (this=0x7fffffffe7c0, Thread1=0x616d98, root=0x604110) at classes.cpp:197
#4  0x00000000004023b7 in Thread_tree::Thread_tree (this=0x7fffffffe7c0, Thread1=0x616d98) at classes.cpp:181
#5  0x0000000000402f03 in main () at main.cpp:19

我不明白问题出在哪里,从我从消息中了解到,程序在第二次调用Tree_insert()时崩溃

【问题讨论】:

  • root=0x1002 这是一个可疑的指针值,尤其是考虑到其余的堆分配指针都高于 0x600000... 您是否留下未初始化的内容,例如 .left.right Tree_node 的成员(尝试在结构定义中将它们默认为 nullptr)?
  • Tree_create是如何实现的?看起来它不只是将this-&gt;root 设置为NULL
  • @Stu 我也这样做了,我得到了同样的错误
  • @Rhathin Tree_create 的身体是这个root = NULL;
  • 我还注意到Tree_empty 返回int。你如何检查这种“空虚”?

标签: c++ c++11


【解决方案1】:

你的问题是Tree_create(this-&gt;node_root);

Tree_create 创建传递给它的指针的副本并将NULL 分配给该副本,而this-&gt;node_root 保持不变并且在调用Tree_sort 时未初始化。

最简单的解决方案是将NULL(或nullptr,在c++11 中更可取)直接分配给this-&gt;node_root

这同样适用于您的其他方法。当您按值传递指针时,对它的任何分配都是在复制时完成的。这里的解决方案是通过引用传递指针(例如Tree_create(Tree_node*&amp; root)

【讨论】:

  • 好吧,你是说我也应该将Tree_sort的参数const Thread *Thread1和构造函数Thread_tree更改为const Thread*&amp; Thread1
  • @stefnto 你没有修改Thread1指针,所以传值就可以了。仅当您需要为其分配新地址时,才通过引用传递指针。
  • 你的回答解决了我的问题,但我稍后仍然遇到分段错误,我可以在这里问你还是我应该提出一个新问题?
  • @stefnto 最好提出新问题,以免这个问题过于宽泛。
猜你喜欢
  • 1970-01-01
  • 2021-07-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-28
  • 2018-03-11
相关资源
最近更新 更多