已分配但未分配的结构
Structure allocated but not assigned
我正在尝试在 C/C++ 中实现 BST。
注意:在此 class 中,提交的文件应具有 .cpp
文件扩展名,并且应使用 C++ 编译器进行编译,但应该是“哲学上”的 C(printf()
, malloc()
,等等),允许某些 C++ 特性(原生 bool
s,等等)。这也意味着解决 C++ 限制(转换 malloc()
的结果,将 const
添加到字符串等)。这条线很模糊,所以为了安全起见,我采用了 C 风格 - 这是一个个人项目,我希望能够通过简单地调整几个关键函数来在需要时回收。
我有一个函数 pushBST()
调用 pushBSTNode()
:
bool pushBST(BST* tree, const char* val_cstr, int val_int) {
if (tree == NULL) return false;
BSTData* data = createBSTData(val_cstr, val_int);
if (data == NULL) return false;
return pushBSTNode(tree->root, tree->root, data);
}
bool pushBSTNode(BSTNode* node, BSTNode* parent, BSTData* data) {
if (node == NULL) {
node = createBSTNode(data, parent);
if (node == NULL) return false;
return true;
} else {
// ...
}
}
我的想法是抽象出使用 pushBST()
将数据推送到 BST,只需要树本身和原始数据。但是,这不起作用,尽管 return 是真的。在 VSCode 中用 GDB 窥视它告诉我有问题,但我不太明白。
调用函数最初按预期工作:
if (tree == NULL) return false; // So it doesn't choke on a void pointer, passed
BSTData* data = createBSTData(...); // It packed the data correctly, passed
if (data == NULL) return false; // Report a failure if the data failed to pack, passed.
此时,我可以看到变量是正确的:树存在并且数据中包含正确的值。接下来是实际推送它的功能:
if (node == NULL) { // tree->root was indeed NULL, passed
node = createBSTNode(...); // This allocates a node and assigns it the packed data, passed
if (node == NULL) return false; // The node exists, passed
return true; // Therefore, this should have worked
}
传入的node
指的是tree->root
,所以应该在那里分配了一个节点结构。在那个函数的最后确实确实node
变量有数据而且数据是正确的(变量parent
是错误的,但我稍后会处理它)。然而,在 returning 到主推送功能时,我看到变量没有改变。变量 tree->root
仍然是 NULL
,但现在它有一个 return 值,表明假定成功。
关于哪里出了问题以及如何解决它有什么想法吗?
这是我使用的测试程序:
main.cpp
:
#include <stdio.h>
#include "bstree.hpp"
int main() {
myds::bst::BST* tree = myds::bst::createBST();
myds::bst::pushBST(tree, "yeet val 1", 5);
myds::bst::pushBST(tree, "yeet val 2", 3);
myds::bst::pushBST(tree, "yeet val 3", 4);
myds::bst::pushBST(tree, "yeet val 4", 1);
myds::bst::pushBST(tree, "yeet val 5", 2);
printf("Hello World!\n");
return 0;
}
bstree.hpp
:
#ifndef BSTREE_HPP
#define BSTREE_HPP
#include <stddef.h>
namespace myds::bst {
struct BSTData {
char val_cstr[16];
int val_int
};
struct BSTNode {
BSTData* data;
BSTNode* parent;
BSTNode* left;
BSTNode* right;
};
struct BST {
BSTNode* root;
};
BSTData* createBSTData(const char* val_cstr, int val_int);
BSTNode* createBSTNode(BSTData* data, BSTNode* parent);
BST* createBST();
bool pushBSTNode(BSTNode* node, BSTNode* parent, BSTData* data);
bool pushBST(BST* tree, const char* val_cstr, int val_int);
}
#endif
bstree.cpp
:
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include "bstree.hpp"
namespace myds::bst {
BSTData* createBSTData(const char* val_cstr, int val_int) {
BSTData* data = (BSTData*) malloc(sizeof(BSTData));
if (data == NULL) return NULL;
strcpy(data->val_cstr, val_cstr);
data->val_int = val_int;
return data;
}
BSTNode* createBSTNode(BSTData* data, BSTNode* parent) {
BSTNode* node = (BSTNode*) malloc(sizeof(BSTNode));
if (node == NULL) return NULL;
node->data = data;
node->parent = parent;
node->left = NULL;
node->right = NULL;
return node;
}
BST* createBST() {
BST* tree = (BST*) malloc(sizeof(BST));
if (tree == NULL) return NULL;
tree->root = NULL;
return tree;
}
bool pushBSTNode(BSTNode* node, BSTNode* parent, BSTData* data) {
if (node == NULL) {
node = createBSTNode(data, parent);
if (node == NULL) return false;
return true;
} else {
ssize_t delta = compareBSTData(data, node->data);
if (delta < 0) {
// data is smaller than current node, should go to left side of node
return pushBSTNode(node->left, node, data);
} else if (delta == 0) {
// data == node, cannot store duplicate values
return false;
} else if (delta > 1) {
// data is larger than current node, should go to the right side of node
return pushBSTNode(node->right, node, data);
}
}
return false; // silence clang
}
bool pushBST(BST* tree, const char* val_cstr, int val_int) {
if (tree == NULL) return false;
BSTData* data = createBSTData(val_cstr, val_int);
if (data == NULL) return false;
bool retval = pushBSTNode(tree->root, tree->root, data);
return retval;
}
}
用于树传播的指针需要通过引用传递。如果按值传递(无引用),则在函数完成后,在 CreateBSTNode 函数范围内所做的任何更改都将丢失。
pushBSTNode(BSTNode* &node, BSTNode* &parent, BSTData* &data)
我正在尝试在 C/C++ 中实现 BST。
注意:在此 class 中,提交的文件应具有 .cpp
文件扩展名,并且应使用 C++ 编译器进行编译,但应该是“哲学上”的 C(printf()
, malloc()
,等等),允许某些 C++ 特性(原生 bool
s,等等)。这也意味着解决 C++ 限制(转换 malloc()
的结果,将 const
添加到字符串等)。这条线很模糊,所以为了安全起见,我采用了 C 风格 - 这是一个个人项目,我希望能够通过简单地调整几个关键函数来在需要时回收。
我有一个函数 pushBST()
调用 pushBSTNode()
:
bool pushBST(BST* tree, const char* val_cstr, int val_int) {
if (tree == NULL) return false;
BSTData* data = createBSTData(val_cstr, val_int);
if (data == NULL) return false;
return pushBSTNode(tree->root, tree->root, data);
}
bool pushBSTNode(BSTNode* node, BSTNode* parent, BSTData* data) {
if (node == NULL) {
node = createBSTNode(data, parent);
if (node == NULL) return false;
return true;
} else {
// ...
}
}
我的想法是抽象出使用 pushBST()
将数据推送到 BST,只需要树本身和原始数据。但是,这不起作用,尽管 return 是真的。在 VSCode 中用 GDB 窥视它告诉我有问题,但我不太明白。
调用函数最初按预期工作:
if (tree == NULL) return false; // So it doesn't choke on a void pointer, passed
BSTData* data = createBSTData(...); // It packed the data correctly, passed
if (data == NULL) return false; // Report a failure if the data failed to pack, passed.
此时,我可以看到变量是正确的:树存在并且数据中包含正确的值。接下来是实际推送它的功能:
if (node == NULL) { // tree->root was indeed NULL, passed
node = createBSTNode(...); // This allocates a node and assigns it the packed data, passed
if (node == NULL) return false; // The node exists, passed
return true; // Therefore, this should have worked
}
传入的node
指的是tree->root
,所以应该在那里分配了一个节点结构。在那个函数的最后确实确实node
变量有数据而且数据是正确的(变量parent
是错误的,但我稍后会处理它)。然而,在 returning 到主推送功能时,我看到变量没有改变。变量 tree->root
仍然是 NULL
,但现在它有一个 return 值,表明假定成功。
关于哪里出了问题以及如何解决它有什么想法吗?
这是我使用的测试程序:
main.cpp
:
#include <stdio.h>
#include "bstree.hpp"
int main() {
myds::bst::BST* tree = myds::bst::createBST();
myds::bst::pushBST(tree, "yeet val 1", 5);
myds::bst::pushBST(tree, "yeet val 2", 3);
myds::bst::pushBST(tree, "yeet val 3", 4);
myds::bst::pushBST(tree, "yeet val 4", 1);
myds::bst::pushBST(tree, "yeet val 5", 2);
printf("Hello World!\n");
return 0;
}
bstree.hpp
:
#ifndef BSTREE_HPP
#define BSTREE_HPP
#include <stddef.h>
namespace myds::bst {
struct BSTData {
char val_cstr[16];
int val_int
};
struct BSTNode {
BSTData* data;
BSTNode* parent;
BSTNode* left;
BSTNode* right;
};
struct BST {
BSTNode* root;
};
BSTData* createBSTData(const char* val_cstr, int val_int);
BSTNode* createBSTNode(BSTData* data, BSTNode* parent);
BST* createBST();
bool pushBSTNode(BSTNode* node, BSTNode* parent, BSTData* data);
bool pushBST(BST* tree, const char* val_cstr, int val_int);
}
#endif
bstree.cpp
:
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include "bstree.hpp"
namespace myds::bst {
BSTData* createBSTData(const char* val_cstr, int val_int) {
BSTData* data = (BSTData*) malloc(sizeof(BSTData));
if (data == NULL) return NULL;
strcpy(data->val_cstr, val_cstr);
data->val_int = val_int;
return data;
}
BSTNode* createBSTNode(BSTData* data, BSTNode* parent) {
BSTNode* node = (BSTNode*) malloc(sizeof(BSTNode));
if (node == NULL) return NULL;
node->data = data;
node->parent = parent;
node->left = NULL;
node->right = NULL;
return node;
}
BST* createBST() {
BST* tree = (BST*) malloc(sizeof(BST));
if (tree == NULL) return NULL;
tree->root = NULL;
return tree;
}
bool pushBSTNode(BSTNode* node, BSTNode* parent, BSTData* data) {
if (node == NULL) {
node = createBSTNode(data, parent);
if (node == NULL) return false;
return true;
} else {
ssize_t delta = compareBSTData(data, node->data);
if (delta < 0) {
// data is smaller than current node, should go to left side of node
return pushBSTNode(node->left, node, data);
} else if (delta == 0) {
// data == node, cannot store duplicate values
return false;
} else if (delta > 1) {
// data is larger than current node, should go to the right side of node
return pushBSTNode(node->right, node, data);
}
}
return false; // silence clang
}
bool pushBST(BST* tree, const char* val_cstr, int val_int) {
if (tree == NULL) return false;
BSTData* data = createBSTData(val_cstr, val_int);
if (data == NULL) return false;
bool retval = pushBSTNode(tree->root, tree->root, data);
return retval;
}
}
用于树传播的指针需要通过引用传递。如果按值传递(无引用),则在函数完成后,在 CreateBSTNode 函数范围内所做的任何更改都将丢失。
pushBSTNode(BSTNode* &node, BSTNode* &parent, BSTData* &data)