繁体   English   中英

将 void-pointer 元素复制到 void-pointer 数组会导致数组中元素的多个副本

[英]Copying void-pointer element into void-pointer array causes multiple copies of element in array

我正在尝试在 C89 中编写 TreeSort function 以使用 qsort 参数进行练习,即(void* base, size_t num, size_t size, int (*compare)(const void*, const void*)) 我已经实现了 sort function, BST 但我不能做一件事:将数据从 BST 移动到原始数组base

我有这种树节点:

struct TreeNode {
    void* val;
    struct TreeNode* left;
    struct TreeNode* right;
};

这棵树插入 function:

struct TreeNode* Insert(struct TreeNode* root, void* val,
                        int (*compare)(const void*, const void*)) {
    if (root == 0) {
        root = (struct TreeNode*) malloc(sizeof(struct TreeNode));
        root->val = val;
        root->left = 0;
        root->right = 0;
        return root;
    }

    if ((*compare) ((void*) val, (void*) root->val) <= 0) {
        root->left = Insert(root->left, val, compare);
    } else if ((*compare) ((void*) val, (void*) root->val) > 0) {
        root->right = Insert(root->right, val, compare);
    }

    return root;
}

这种排序 function:

int16_t CEcoLab1_TreeSort(/* in */ void* base,
                          /* in */ size_t num,
                          /* in */ size_t size,
                          /* in */ int (*compare)(const void*, const void*)) {
    struct TreeNode* bst = 0;
    int ptr = 0;
    int i = 0;

    if (me == 0 || base == 0 || compare == 0) {
        return -1;
    }

    for (i = 0; i < num; ++i) {
        bst = Insert(bst, (char_t*) base + (size * i), compare);
    }

    Write_Inorder(bst, base, num, size, &ptr);

    Destroy(bst);

    return 0;
}

并尝试像这样在base数组中写入数据。 ptr指向我们必须写入数字的当前索引。

void Write_Inorder(struct TreeNode* root,
                   void* target,
                   size_t num,
                   size_t size,
                   int* ptr) {
    if (root != 0) {
        Write_Inorder(root->left, target, num, size, ptr);

        memcpy((char_t*) target + (size * (*ptr)++), root->val, size);

        Write_Inorder(root->right, target, num, size, ptr);
    }
}

这会导致这样的行为。 输出

我不知道为什么会这样,但它可能与ptr增量有关,因为当索引被硬编码时,所有问题都消失了。 BST 也可以正常工作,我什至可以使用printf("%d ", *(int32_t*) root->val);

希望有人阅读这篇文章并能有所帮助...提前致谢。

Reprex(VS 2022编译)

而不是

// weak
if ((*compare) ((void*) val, (void*) root->val) <= 0) {
    root->left = Insert(root->left, val, compare);
} else if ((*compare) ((void*) val, (void*) root->val) > 0) {
    root->right = Insert(root->right, val, compare);
}

简化和检测BST 不允许两个节点具有相同值的相等

// replacement
int cmp = compare(val, root->val);
if (cmp < 0) {
    root->left = Insert(root->left, val, compare);
} else if (cmp > 0) {
    root->right = Insert(root->right, val, compare);
} else {
    TBD code;
}

暂无
暂无

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

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