繁体   English   中英

通过指针从 kd 树递归打印节点

[英]Issue recursively printing nodes from a kd tree via pointers

首先,如果我在这里做错了,因为这是我第一次发布问题,请原谅我。

谁能告诉我我做错了什么。 当我尝试遍历 kd 树并打印出我的所有点时,我传入的节点的“pnt”属性将其值更改为 memory 地址。 我正在查看“print”和“printPasser”function(两者都位于底部)。 我知道我用指针做错了,但我只是不知道是什么。 如果有人发现其他错误,请发表评论

'''

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

typedef struct node
{
    char axis;
    struct node *left;
    struct node *right;
    unsigned int val;
    struct point *pnt;
    //struct point pnt;
} Node;

typedef Node * NodePtr;

typedef struct point
{
    unsigned int xVal;
    unsigned int yVal;
    char *Datum;
} Point;

typedef Point * PointPtr;

typedef struct kdtree
{
    struct node *root;
    unsigned int xBound;
    unsigned int yBound;
} kdTree;

typedef kdTree *kdTreePtr;

//|--------------------------------------------------

kdTreePtr create();
void insert(kdTree * tree, struct point pntInsert);
void insertVal(kdTree * tree, unsigned int xIn, unsigned int yIn, char * Datum);
struct point repeater(struct node * tmp, struct point * pnt);
void delete(kdTree * tree, struct point * pnt);
void destroy(kdTree * tree);
struct point pop(kdTree * tree);
void print(kdTree * tree);
void printPasser(struct node * root);

void insertAlt(kdTree * tree, struct point pntInsert);
void insertPasser(Node * root, struct point pntInsert);
struct point nearestNeighbor(kdTree * tree, struct point * pntInit);
struct point nearestNicestNeighbor(kdTree * tree, struct point * pntInit);
void scale(kdTree * tree, unsigned int xScaler, unsigned int yScaler);
void resize(kdTree * tree, unsigned int xBound, unsigned int yBound);

void analyze(struct node *root);

//|--------------------------------------------------

int main(void)
{
    kdTree * basic;
    basic = malloc(sizeof(kdTreePtr));
    basic = create();
    resize(basic, 30, 30);

    //Point pntr;
    Point pnt1;
    Point* pntr1 = &pnt1;
    pntr1->xVal = 2;
    pntr1->yVal = 7;
    pntr1->Datum = "Big";

    Point pnt2;
    Point* pntr2 = &pnt2;
    pntr2->xVal = 3;
    pntr2->yVal = 8;
    pntr2->Datum = "Bigger";

    print(basic);

    insertAlt(basic, pnt1);
    printf("Point: (%u,%u) main tester\n", basic->root->pnt->xVal, basic->root->pnt->yVal);
    print(basic);
    insert(basic, pnt2);
    print(basic);
    return 0;
}

kdTreePtr create()
{
    kdTreePtr newTree = malloc(sizeof(kdTree));
    newTree->xBound = 0;
    newTree->yBound = 0;
    newTree->root = malloc(sizeof(NodePtr));
    newTree->root->left = NULL;
    newTree->root->right = NULL;
    newTree->root->pnt = NULL;
    return newTree;
}

void resize(kdTree * tree, unsigned int xBound, unsigned int yBound)
{
    tree->xBound = xBound;
    tree->yBound = yBound;
}

void insertAlt(kdTree * tree, struct point pntInsert)
{
    if (tree->root->pnt == NULL && tree->root->left == NULL && tree->root->right == NULL)
    {
        puts("empty");
        //if(tree->root->pnt != NULL)
        //    printf("Point: (%u,%u) root\n", tree->root->pnt->xVal, tree->root->pnt->yVal);
        tree->root->pnt = &pntInsert;
        printf("Point: (%u,%u) root end\n", tree->root->pnt->xVal, tree->root->pnt->yVal);
    }
    else
    {
        puts("Iterate");
        insertPasser(tree->root, pntInsert);
    }
}

void insertPasser(Node * root, struct point pntInsert)
{
    if (root->pnt == NULL && root->left != NULL && root->right != NULL)
    {
        if (root->axis == 'y')
        {
            if (pntInsert.yVal >= root->pnt->yVal)
                insertPasser(root->right, pntInsert);
            else
                insertPasser(root->left, pntInsert);
        }
        else
        {
            if (pntInsert.xVal >= root->pnt->xVal)
                insertPasser(root->right, pntInsert);
            else
                insertPasser(root->left, pntInsert);
        }
    }

    else
    {
        Node *leftChild;
        Node *rightChild;
        rightChild = malloc(sizeof(NodePtr));
        leftChild = malloc(sizeof(NodePtr));

        unsigned int lower;
        unsigned int xDif,yDif;

        if (pntInsert.xVal >= root->pnt->xVal)
        {
            xDif = abs(pntInsert.xVal - root->pnt->xVal); 
            lower = root->pnt->xVal;
        }
        else
        {   
            xDif = abs(root->pnt->xVal - pntInsert.xVal); 
            lower = pntInsert.xVal;
        }
        if (pntInsert.yVal >= root->pnt->yVal)
        {
            yDif = abs(pntInsert.yVal - root->pnt->yVal) ;
            lower = root->pnt->yVal;
        }
        else
        {
            yDif = abs(root->pnt->yVal - pntInsert.yVal) ;
            lower = pntInsert.yVal;
        }

        if (xDif >= yDif)
        {
            root->axis = 'y';
            root->val = ((unsigned int)xDif / 2) + lower;

            if (pntInsert.xVal >= root->pnt->xVal)
            {
                puts("test 1");

                rightChild->pnt = &pntInsert;
                leftChild->pnt = root->pnt;

                root->right = rightChild;
                root->left = leftChild;

                root->pnt = NULL;
            }
            else
            {
                puts("test 2");

                rightChild->pnt = root->pnt;
                leftChild->pnt = &pntInsert;

                *(root->right) = *rightChild;
                *(root->left) = *leftChild;

                root->pnt = NULL;
            }
        }
        else
        {
            root->axis = 'x';
            root->val = ((unsigned int)yDif / 2) + lower;

            if (pntInsert.yVal >= root->pnt->yVal)
            {
                puts("test 3");

                rightChild->pnt = &pntInsert;
                leftChild->pnt = root->pnt;

                root->right = rightChild;
                root->left = leftChild;

                root->pnt = NULL;
            }
            else
            {
                puts("test 4");

                rightChild->pnt = root->pnt;
                leftChild->pnt = &pntInsert;

                root->right = rightChild;
                root->left = leftChild;

                root->pnt = NULL;
            }
        }
    }
}

void insertVal(kdTree * tree, unsigned int xIn, unsigned int yIn, char * Datum)
{
    Point pntInsert;
    PointPtr pntInsertPtr = &pntInsert;
    pntInsert.xVal = xIn;
    pntInsert.yVal = yIn;
    pntInsert.Datum = Datum;
    insertAlt(tree, pntInsert);

    //printf("%u,", tree->root->pnt->xVal);
    //printf("%u\n", tree->root->pnt->yVal);
    //printf("%u,", tree->root->pnt->yVal);
    //printf("%u\n", tree->root->pnt->xVal);
}


void print(kdTree * tree)
{
    if (tree->root->pnt == NULL && tree->root->left == NULL && tree->root->right == NULL)
        puts("blank");
    else 
    {
        printf("Point: (%u,%u) \n", tree->root->pnt->xVal, tree->root->pnt->yVal);
        printPasser(tree->root);
    }
}

void printPasser(struct node * root)
{
    printf("Point: (%u,%u) \n", root->pnt->xVal, root->pnt->yVal);
    //PointPtr rootHolder = 
    if (root->left == NULL && root->right == NULL && root->pnt != NULL)
    {
        printf("Point: (%u,%u) \n", root->pnt->xVal, root->pnt->yVal);
    }
    else
    {
        printPasser(root->left);
        printPasser(root->right);
    }
}

'''

一切看起来都很好,直到我将节点指针传递到“printPasser”function 中,在那里我取根点并获得一个新值,该值看起来只是转换为无符号整数的指针值。

我在您的代码中发现了以下与内存相关的问题:

    kdTree * basic;
    basic = malloc(sizeof(kdTreePtr));
    basic = create();

您初始化basic两次。 这本身不是问题,但会导致大小为kdTreePtr的 memory 泄漏。 删除第一个作业。

    newTree->root = malloc(sizeof(NodePtr));

每当您分配一个新的Node时,您只分配一个指针大小的 memory 块,而不是适合Node的大小。 您需要分配sizeof(Node)字节。 有多次出现。

修复这些后,您的代码不再触发分段错误(在启用优化的情况下编译时),并且 output 保持稳定。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM