【问题标题】:C - Changint the order of the elements of a struct causes Segmentation faultC - 更改结构元素的顺序会导致分段错误
【发布时间】:2017-06-01 06:12:52
【问题描述】:

我一直在学习 C 中的数据结构和算法,但在更改结构元素的顺序时遇到了问题

这是我的 lib.h 文件:

    typedef struct ElementType
    {
        int id;
        char name[20];
    } ElementType;


    typedef struct Node
    {
        ElementType data;

        struct Node* left;
        struct Node* right;
    } Node;


    Node* insert(Node** tree, ElementType e)
    {
        if( (*tree) == NULL )
        {
            (*tree)=(Node*)malloc(sizeof(Node));

            (*tree)->data = e;

            (*tree)->left = NULL;
            (*tree)->right = NULL;

            return (*tree);
        }

        else if ((*tree)->data.id == e.id)
            return (*tree);

        else if (e.id < (*tree)->data.id)
            return insert( &((*tree)->left), e);

        else
            return insert( &((*tree)->right), e);
    }

    void freeTree(Node* tree)
    {

        if((tree) == NULL)
            return;

        else
        {
            freeTree(tree->left);
            freeTree(tree->right);

            free(tree);
        }
    }

    void inorder(Node* tree)
    {
        if(tree!=NULL)
        {
            inorder(tree->left);

            printf("%d - %s\n", tree->data.id, tree->data.name);
            printf("This node  : %p\n", tree);
            printf("This data  : %p\n", &(tree->data));
            printf("This left  : %p\n", tree->left);
            printf("This right : %p\n", tree->right);

            inorder(tree->right);
        }
    }


    void init(Node** tree)
    {
        (*tree) = NULL;
    }

这是我的主文件,包含上面的库

ElementType makeNewElem(int a, char* b)
{
    ElementType e;
    e.id = a;
    strcpy(e.name, b);

    return e;
}

int main() {

    Node* root;

    init(&root);
    ElementType a = makeNewElem(5, "A");
    ElementType b = makeNewElem(6, "B");
    ElementType c = makeNewElem(7, "C");

    insert(&root, a);
    insert(&root, b);
    insert(&root, c);

    inorder(root);
    printf("\n");
    freeTree(root);
    inorder(root);
    return 0;
}

这是我编译后的结果

5 - A
This node  : 0x1671010
This data  : 0x1671010
This left  : (nil)
This right : 0x1671040
6 - B
This node  : 0x1671040
This data  : 0x1671040
This left  : (nil)
This right : 0x1671070
7 - C
This node  : 0x1671070
This data  : 0x1671070
This left  : (nil)
This right : (nil)

23531568 - 
This node  : 0x1671010
This data  : 0x1671010
This left  : (nil)
This right : 0x1671040
23531616 - 
This node  : 0x1671040
This data  : 0x1671040
This left  : (nil)
This right : 0x1671070
0 - 
This node  : 0x1671070
This data  : 0x1671070
This left  : (nil)
This right : (nil)

然后在我移动“ElementType data;”行之后

typedef struct Node
{
    struct Node* left;
    struct Node* right;

    ElementType data;
} Node;

控制台>>

5 - A
This node  : 0x1226010
This data  : 0x1226020
This left  : (nil)
This right : 0x1226040
6 - B
This node  : 0x1226040
This data  : 0x1226050
This left  : (nil)
This right : 0x1226070
7 - C
This node  : 0x1226070
This data  : 0x1226080
This left  : (nil)
This right : (nil)

Segmentation fault (core dumped)

谁能帮我解释一下原因 1.在我改代码之前,为什么还是打印出data的值(我虽然节点free-ed后会是NULL!?) 2. 修改代码后为什么会被core-dump?

我很抱歉我的长问题和我糟糕的英语!

【问题讨论】:

  • 未定义的行为是未定义的。
  • 改变结构成员的顺序应该对正确的程序没有影响。如果它导致错误,您可能在程序的某个地方有未定义的行为。使用调试器单步调试程序以查看何时出现问题。
  • 您正在释放您的树,然后您立即致电inorder(root);。那么你期待什么呢?
  • @dOshu 你把freeTree()改成*tree =NULL;了吗?
  • @dOshu 但这就是他建议的重点——freeTree 需要将树设置为 NULL,以便inorder() 不会尝试打印释放的条目。

标签: c struct segmentation-fault


【解决方案1】:
...
freeTree(root);
inorder(root);
...

你在这里期待什么?这会导致未定义的行为:有时它可能有效,有时可能无效。

删除freeTree 语句,它会正常工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-27
    • 2017-08-09
    • 2020-04-09
    • 1970-01-01
    • 2021-03-19
    • 1970-01-01
    相关资源
    最近更新 更多