簡體   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