C++链表单元测试returns段错误

C++ Linked list unit test returns segment fault

我实现链表的算法如下

linkedList.hpp

#include <cstddef>

class LinkedList{
  public:
    int value {0};
    LinkedList* nextNode {NULL};
};

LinkedList* addNewNode(int nodeVal){

  LinkedList *newNode;
  newNode->value = nodeVal;
  newNode->nextNode = nullptr;

  return newNode;
}

下面googletest单元测试检查是否

linkedListTest.cpp

#include <gtest/gtest.h>
#include "../linkedList.hpp"

int main(int argc, char **argv){
    ::testing::InitGoogleTest(&argc,argv);
    return RUN_ALL_TESTS();

}

class LinkedListTest : public ::testing::Test{

    public:
        LinkedList *linkedlist = new LinkedList();
        virtual void SetUp(){
            }
        virtual void TearDown(){
            delete linkedlist;
        }
};
TEST_F(LinkedListTest,addNewNodeReturnsItsNodePointer){

    // act
    linkedlist = addNewNode(5);

    EXPECT_TRUE(linkedlist != nullptr);
    ASSERT_EQ(linkedlist->value,5);
    EXPECT_TRUE(linkedlist->nextNode != nullptr);

}

当我运行这段代码时,测试通过但我得到

Segmentation fault

我错过了什么?

newNode in addNewNode 从未被初始化,所以它是指向任何地方的指针:

LinkedList* addNewNode(int nodeVal) {
  LinkedList *newNode;  // Uninitialized, so undefined
  newNode->value = nodeVal;  // `->` dereferences the pointer, but it goes nowhere!

初始化它的一种方法是使用堆分配,即运算符 new - 但请记住,您需要在 C++ 中管理资源,因此您需要 free 使用完毕后。

  LinkedList* addNewNode(int nodeVal) {
      LinkedList *newNode = new LinkedList();
      newNode->value = nodeVal;
      newNode->nextNode = nullptr;

稍后,要释放内存,您可以这样做:

if (myNode->nextNode != nullptr) {
    delete myNode->nextNode;
    myNode.nextNode = nullptr;
}

但是如果你想删除整个 LinkedList,你首先必须走到它的 end 并从那里开始删除。如果在删除其后继节点之前删除了一个节点,则会造成内存泄漏 bc。您不再有释放该内存的指针。

还要确保打开编译器警告!默认设置 way 太宽松了。例如,对于 GCC,您可以使用 -Wall。这告诉我:

<source>: In function 'LinkedList* addNewNode(int)':
<source>:12:18: warning: 'newNode' is used uninitialized [-Wuninitialized]
   12 |   newNode->value = nodeVal;
      |   ~~~~~~~~~~~~~~~^~~~~~~~~

当您遇到段错误 (segfault) 时,您应该在调试模式下编译您的程序,然后 运行 在调试器中编译它。它可以告诉你错误发生在哪里:

gcc -g -Og -o myprog myprog.c
gdb ./myprog
run
(segfault)
backtrace