我在VS2013中运行Microsoft C ++ UnitTest
时遇到了一个奇怪的问题。
每次在IDE中执行Run All
测试时测试失败,但是当我在特定测试中使用Run Selected Tests
时,测试成功。
我正在测试的是使用我自己的BinarySearchTree
课程。如果失败,将返回异常代码C0000005
(这可能是由于指针的内部链接错误)。
那么这可能是什么原因?
测试在最后一段代码中失败,我在其中生成随机ID字符串,将它们单独添加到我的BST
并随机删除它们,直到整个BST
再次为空。
BinarySearchTree clientList;
Client client;
// test random adding & deletion
std::vector<std::string> idAddList;
for (unsigned int i = 0; i < 100; i++)
idAddList.push_back(randomID(20));
std::vector<std::string> idRemoveList;
unsigned int id;
while (idAddList.size() > 0)
{
// pick random id from list and delete it
id = rand() % idAddList.size();
client.uniqueID = idAddList.at(id);
clientList.add(client);
if (clientList.lastICLResult() == iList::ICLResult::OK)
idRemoveList.push_back(idAddList.at(id));
idAddList.erase(idAddList.begin() + id);
}
while (idRemoveList.size() > 0)
{
// pick random client from list and delete it
id = rand() % idRemoveList.size();
clientList.remove(idRemoveList.at(id));
if (clientList.lastICLResult() == iList::ICLResult::OK)
idRemoveList.erase(idRemoveList.begin() + id);
}
Assert::AreEqual<unsigned int>(0, clientList.size());
这里是randomID()
函数的代码:
std::string randomID(const unsigned int maxLength)
{
static const char alphanum[] =
"0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"öÖäÄüÜ"
"!=[]$%&";
std::string result;
for (unsigned int i = 0; i < maxLength; i++)
result += alphanum[rand() % (sizeof(alphanum - 1))];
return result;
}
此问题的相关特定于类的代码将是removeMatch()
函数和相应的Node
类。 BST
将Client
类作为其add()
函数的数据对象,并且只有在其{ID 1}}中的ID字符串尚未添加时才添加给定客户端。内部还有函数BST
和fetchMinNode()
,它们可以检索指向fetchMaxNode()
中最左侧或最右侧节点的指针。主/根节点名为BST
,如果m_rootNode
变空,则会为其分配nullptr
。
如果是BST
函数,我总是寻找要删除的节点的正确子节点/子树,并且 - 如果可能 - 在特定位置重新分配内部节点树。
removeMatch()
[私人] void iList::removeMatch(Node* toBeDeletedNode)
{
if (toBeDeletedNode)
{
// IN CASE GIVEN NODE IS THE ROOT NODE
if (!toBeDeletedNode->parent)
{
// Case 1: root node is the only node in the BST
if (!toBeDeletedNode->left && !toBeDeletedNode->right)
handleRootLeaf(toBeDeletedNode);
// Case 2: either both child nodes are available or just the right
// child node is available
else if ((toBeDeletedNode->left && toBeDeletedNode->right) || toBeDeletedNode->right)
handleRootRSubtree(toBeDeletedNode);
// Case 3: only left child node is present
else
handleRootLSubtree(toBeDeletedNode);
}
// IN CASE GIVEN NODE IS ANY CHILD NODE
else
{
// Case 1: if given node is a leaf node
if (!toBeDeletedNode->left && !toBeDeletedNode->right)
handleChildLeaf(toBeDeletedNode);
// Case 2: if given node has either both child nodes or just a right child node
else if ((toBeDeletedNode->left && toBeDeletedNode->right) || toBeDeletedNode->right)
handleChildRSubtree(toBeDeletedNode);
// Case 3: if given node has only a left child node
else
handleChildLSubtree(toBeDeletedNode);
}
m_elementCount--;
}
}
handleRootLSubtree()
[私人] void handleRootLSubtree(Node* toBeDeletedNode)
{
// fetch max node in left subtree
Node* maxNode = fetchMaxNode(toBeDeletedNode->left);
// in case left child node is the max node
if (maxNode->parent != toBeDeletedNode)
{
if (maxNode->left)
{
maxNode->left->parent = maxNode->parent;
maxNode->parent->right = maxNode->left;
}
else
maxNode->parent->right = nullptr;
maxNode->left = toBeDeletedNode->left;
maxNode->parent->parent = maxNode;
}
maxNode->parent = nullptr;
// cut linkage
toBeDeletedNode->left = nullptr;
delete toBeDeletedNode;
m_rootNode = maxNode;
}
handleRootRSubtree()
[私人] void handleRootRSubtree(Node* toBeDeletedNode)
{
// fetch min node in right subtree
Node* minNode = fetchMinNode(toBeDeletedNode->right);
// in case right child node isn't the min node
if (minNode->parent != toBeDeletedNode)
{
if (minNode->right)
{
minNode->right->parent = minNode->parent;
minNode->parent->left = minNode->right;
}
else
minNode->parent->left = nullptr;
minNode->right = toBeDeletedNode->right;
toBeDeletedNode->right->parent = minNode;
}
minNode->left = toBeDeletedNode->left;
minNode->parent = nullptr;
if (toBeDeletedNode->left)
toBeDeletedNode->left->parent = minNode;
// cut linkage
toBeDeletedNode->left = nullptr;
toBeDeletedNode->right = nullptr;
delete toBeDeletedNode;
m_rootNode = minNode;
}
handleRootLeaf()
[私人] void handleRootLeaf(Node* toBeDeletedNode)
{
delete m_rootNode;
m_rootNode = nullptr;
}
handleChildLSubtree()
[私人] void handleChildLSubtree(Node* toBeDeletedNode)
{
// fetch max node in left subtree
Node* maxNode = fetchMaxNode(toBeDeletedNode->left);
// in case left child node is the max node
if (maxNode->parent == toBeDeletedNode)
maxNode->parent = toBeDeletedNode->parent;
else
{
if (maxNode->left)
{
maxNode->left->parent = maxNode->parent;
maxNode->parent->right = maxNode->left;
}
else
maxNode->parent->right = nullptr;
maxNode->left = toBeDeletedNode->left;
toBeDeletedNode->left->parent = maxNode;
maxNode->parent = toBeDeletedNode->parent;
}
if (toBeDeletedNode->parent->left
&& toBeDeletedNode->parent->left == toBeDeletedNode)
toBeDeletedNode->parent->left = maxNode;
else
toBeDeletedNode->parent->right = maxNode;
// cut linkage
toBeDeletedNode->left = nullptr;
toBeDeletedNode->right = nullptr;
delete toBeDeletedNode;
}
handleChildRSubtree()
[私人] void handleChildRSubtree(Node* toBeDeletedNode)
{
// fetch min node in right subtree
Node* minNode = fetchMinNode(toBeDeletedNode->right);
// in case right child node is the min node
if (minNode->parent == toBeDeletedNode)
{
if (toBeDeletedNode->left)
{
minNode->left = toBeDeletedNode->left;
toBeDeletedNode->left->parent = minNode;
}
minNode->parent = toBeDeletedNode->parent;
}
else
{
if (minNode->right)
{
minNode->right->parent = minNode->parent;
minNode->parent->left = minNode->right;
}
else
minNode->parent->left = nullptr;
minNode->left = toBeDeletedNode->left;
if (toBeDeletedNode->left)
toBeDeletedNode->left->parent = minNode;
minNode->right = toBeDeletedNode->right;
toBeDeletedNode->right->parent = minNode;
minNode->parent = toBeDeletedNode->parent;
}
if (toBeDeletedNode->parent->left
&& toBeDeletedNode->parent->left == toBeDeletedNode)
toBeDeletedNode->parent->left = minNode;
else
toBeDeletedNode->parent->right = minNode;
// cut linkage
toBeDeletedNode->left = nullptr;
toBeDeletedNode->right = nullptr;
delete toBeDeletedNode;
}
handleChildLeaf()
void handleChildLeaf(Node* toBeDeletedNode)
{
if (toBeDeletedNode->parent->left
&& toBeDeletedNode->parent->left == toBeDeletedNode)
toBeDeletedNode->parent->left = nullptr;
else
toBeDeletedNode->parent->right = nullptr;
delete toBeDeletedNode;
}
上课:
Node
答案 0 :(得分:0)
错误原因在于handleRootLSubtree()
函数:
该行
maxNode-&gt; parent-&gt; parent = maxNode;
必须替换为
toBeDeletedNode-&gt; left-&gt; parent = maxNode;