简体   繁体   中英

Issue recursively printing nodes from a kd tree via pointers

Firstly, forgive me if i do something wrong here since its my first time posting a question.

Can anyone tell me what i am doing incorrectly. When i attempt to iterate through a kd tree and print off all of my points, the 'pnt' attribute to the node i pass in changes its value to a memory address. I am looking at the 'print' and 'printPasser' function (both are located at the bottom). I know i'm doing something wrong with pointers but i just don't know what. If anyone spots something else wrong, please do comment

'''

#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);
    }
}

'''

everything looks alright until i pass the node pointer into the 'printPasser' function where i take the point of root and get a new value that just looks to be the pointer values cast to an unsigned int.

I identified the following memory-related issues in your code:

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

You initialize basic twice. This is not a problem in itself, but it results in a memory leak of size kdTreePtr . Remove the first assignment.

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

Whenever you allocate an new Node , you only allocate a pointer-sized chunk of memory, not the size appropriate for a Node . You need to allocated sizeof(Node) bytes. There are multiple occurrences.

After fixing those, your code does not trigger a segmentation fault anymore (when compiling with optimizations enabled) and the output remains stable.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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