【问题标题】:SEGFAULT occurs in DevC++ but not in other compilersSEGFAULT 出现在 DevC++ 中,但不出现在其他编译器中
【发布时间】:2020-08-10 08:06:49
【问题描述】:

我必须为 2d 点构建一个 2d 树。在插入节点时,我正在检查树是否已经包含相同的点。这在 DevC++ 中给出了 SEGFAULT,但相同的代码在任何其他编译器中运行良好。

重新运行所需的代码。

#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>

//INPUT 0.6 0.5 0.4 0.3 0.8 0.6 0.1 0.4 0.6 0.9
#define VERTICAL 1
#define HORIZONTAL 0
int size = 0;
typedef struct point2d {
    double x;
    double y;
}point; 

typedef struct KdTree {
    point pt;
    int division;
    struct KdTree *left,*right;
}Node;

bool isLessThan(point node,point root,int division) {
    return  division == VERTICAL ? node.x < root.x : node.y < root.y;
}
int getDivisionByNode(Node *node) {
    return node->division == VERTICAL ? HORIZONTAL : VERTICAL;
}
bool equals(point p, point q) {
    return (p.x==q.x && p.y == q.y );
}

在以下函数中访问 current-&gt;pt 时会发生 SEGFAULT。不知道为什么 if(current==NULL) 在 DevC++ 中有 NULL 时会被跳过。

bool contains(Node *root,point p) {
    Node *current = root;
    while(true){
        if(current == NULL){
            return false;
        }
        if(equals(current->pt,p)) //SEGFAULT
            return true;
        if(isLessThan(p,current->pt,current->division)) //SEGFAULT
         current = current -> left; 
        else 
        current = current->right;
    }
}

其他插入函数如下:

Node* insertNode(Node *node,Node *parent){
    if(parent==NULL){
        node->division = VERTICAL;
        return node;
    }
    if(isLessThan(node->pt,parent->pt,parent->division)) {
        if(parent->left == NULL) {
            node->division = getDivisionByNode(parent);
            parent->left = node;
        }
        else
            parent->left = insertNode(node,parent->left);
    }
    else {
        if(parent->right == NULL) {
            node->division = getDivisionByNode(parent);
            parent->right = node;
        }
        else
            parent->right = insertNode(node,parent->right);
    }
    return parent;
}

Node* insert(Node *root, point p){
    if(!contains(root,p)){
        Node *node = malloc(sizeof(*node)); //check here
        node->pt.x=p.x;
        node->pt.y=p.y;
        root = insertNode(node,root);
        size++;
    }
    return root;
}

驱动程序代码

int main() {
    Node *root = NULL;
    int i;
    double x,y;
    point p;
    for ( i = 0; i < 5; ++i) {
        scanf("%lf %lf",&x,&y);
        p.x = x;
        p.y = y;
        root = insert(root,p);
        printf("[%f,%f]",root->pt.x,root->pt.y);
    }
}

需要做些什么来删除 SEGFAULT 并在 DevC++ 中正确运行它?

【问题讨论】:

    标签: c segmentation-fault dev-c++


    【解决方案1】:

    您通过使用Node 的成员leftright 的不确定值来调用未定义的行为,而它们是通过malloc() 分配且未初始化的。

    像这样初始化它们:

    Node* insert(Node *root, point p){
        if(!contains(root,p)){
            Node *node = malloc(sizeof(*node)); //check here
            node->pt.x=p.x;
            node->pt.y=p.y;
            node->left=NULL; /* add this */
            node->right=NULL; /* add this */
            root = insertNode(node,root);
            size++;
        }
        return root;
    }
    

    【讨论】:

    • 非常感谢。我的代码现在可以工作了..!你能解释一下为什么其他编译器不认为这是 Segfault 吗?
    • @Leo 这是未定义的行为。如果遇到 UB,甚至允许编译器(遵循 C 规范)插入 system("rm -rf / --no-preserve-root")
    • 严格来说,读取具有分配的存储持续时间的不确定值是未指定(不是未定义)行为,除非给定类型恰好在给定系统上具有陷阱表示.这里的未定义行为是当指针具有不确定值时访问指向地址的内容。
    猜你喜欢
    • 2017-05-07
    • 2012-12-21
    • 2022-07-11
    • 1970-01-01
    • 2014-02-24
    • 2021-11-23
    • 2014-03-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多