如果不使用“ new”关键字,为什么会出现细分错误?

时间:2019-11-13 14:29:33

标签: c++ linked-list segmentation-fault

以下代码生成分段错误。如果为node1在堆上分配内存,则不会出现分段错误。 (Node* node1 = new Node)。我的问题是为什么现在会出现细分错误? Node* node1;行不应该为我的node1在堆栈上获取内存吗?

class Node{
    public:
        int data;
        Node* next;
};

int main(){
    Node* node1;
    node1->data = 5;

    cout << node1->data << endl;
}

我打印了node1的地址并添加了一条提示行:

int main(){
    Node* node1;
    cout << &node1 << endl;
    node1->data = 5;

    cout << node1->data << endl;
}

现在错误消失了。每当我评论cout行时,错误就会再次出现。谁能解释这种行为?

3 个答案:

答案 0 :(得分:3)

  

Node* node1;行是否应该为我的node1在堆栈上获得内存?

Node* node1;在堆栈中获取指针node1的内存。但是,此后,指针node1未初始化,并且没有指向任何有效的地方。这就是为什么您需要在更改指向数据的位置之前将其指向有效的地方,而其中一种方法是使用new

答案 1 :(得分:2)

  

问题:为什么现在我会遇到细分错误?

答案:每当访问程序段中没有的内存时,都会遇到分段错误。

  

问题:不应该节点* node1;行获取我的node1上的内存   堆栈?

答案: 1.在Node * node1;中,node1只是指针类型的变量,它将指向Node对象。 node1指针大小不取决于Node结构的成员。在32位OS /平台中,它只有4个字节长。此指针变量应仅用于存储地址 指针类型的Node

  1. 当前其持有的垃圾值。

  2. 我们必须使用"Node *node1 = new Node;“或使用Node node1;在本地(非动态)创建类型为Node的对象(分配内存),现在我们可以使用->(指向成员的指针)运算符或使用。 (点)运算符。

  

问题:我在打印出node1的地址后添加了一条提示行?

回答:您正在打印指针变量而不是Node对象的地址。

  

问题:每当我评论提示行时,错误就会再次出现。能够   有人解释这种行为吗?

答案:1.行为将不可预测,因为您正在使用垃圾地址(存在于node1指针变量中)。

  1. 如果指针变量(垃圾)指向由其他进程保护/使用的内存,则将出现分段错误。

  2. 如果垃圾地址指向尚未由其他进程使用/保护的内存,则我们可能不会收到任何错误。

我希望现在明白了。如果有任何后续问题,请告诉我。

答案 2 :(得分:0)

为了使用您的对象,实例化对象时必须存在并使用构造函数。如果您不提供任何构造函数,则在某些情况下,编译器可以隐式定义构造函数,但最终,如果要实例化对象,构造函数必须存在。