诡异的问题,求高手解答

xyalter 2010-07-08 06:59:13
我今天在写一个数据结构的程序的时候,遇到一个很诡异的问题。

首先,我定义了一个双链表。

代码如下:


struct ListNode_t
{
struct ListNode_t *prior;
struct ListNode_t *next;
void *data;
};

typedef struct ListNode_t ListNode_t;

struct List_t
{
ListNode_t *head;
ListNode_t *tail;
int count;
};

typedef struct List_t List_t;


进行了一些基本的测试,没有问题。

又定义了一个树。

代码如下:


struct TreeNode_t
{
struct TreeNode_t *root;
struct TreeNode_t *parent;
struct List_t *child;
int depth;
void *data;
};

typedef struct TreeNode_t TreeNode_t;

struct Tree_t
{
struct TreeNode_t *root;
int depth;
};

typedef struct Tree_t Tree_t;


在写树的遍历的时候,遇到了问题。

代码如下:


int TraverseTree(Tree_t *eTree, void (*visit)())
{
if (TreeEmpty(eTree))
return DSC_FAIL;

TraverseNode(eTree->root, visit);

return DSC_OK;
}


TraverseNode开始真正的遍历。

代码如下:


void TraverseNode(TreeNode_t *eNode, void (*visit)())
{
visit(eNode);

if (!ListEmpty(eNode->child))
TraverseList2(eNode->child, TraverseChild, visit);
}


问题出现在这里。

我原先的写法是:


void TraverseNode(TreeNode_t *eNode, void (*visit)())
{
visit(eNode);

if (!ListEmpty(eNode->child))
TraverseList(eNode->child, visit);
}


但是这样子,无法遍历到下一层节点。

所以我写了TraverseList2。

代码如下:


void TraverseList2(List_t *eList, void (*visit)(), void (*visit2)())
{
int i;

for (i=1;i<=eList->count;i++)
visit(GetListNode(eList, i), visit2);
}


回头看TraverseNode。


void TraverseNode(TreeNode_t *eNode, void (*visit)())
{
visit(eNode);

if (!ListEmpty(eNode->child))
TraverseList2(eNode->child, TraverseChild, visit);
}


传递给了TraverseList2一个TraverseChild。

代码如下:


void TraverseChild(ListNode_t *eNode, void (*visit)())
{
TraverseNode((TreeNode_t*)eNode->data, visit);
}


这样子我想就可以完成遍历了。

结果测试的时候出现了很奇怪的错误。

测试代码如下:


void printTree(TreeNode_t *eNode)
{
printf("%d\n", *(int*)eNode->data);
}

int TestTree()
{
int *tmpInt;
Tree_t *tree1;

printf("\n");
printf("\n");

printf("TestTree is start!\n");

printf("\n");
printf("\n");



tree1 = CreateTree();

InitTree(tree1);

CreateTree(tree1);

InsertNullChildNodes(tree1->root, 0, 2);

tmpInt = malloc(sizeof(int));
*tmpInt = 0;

tree1->root->data = tmpInt;

tmpInt = malloc(sizeof(int));
*tmpInt = 1;

((ListNode_t*)GetListNode(tree1->root->child, 1)->data)->data = tmpInt;

tmpInt = malloc(sizeof(int));
*tmpInt = 2;

((ListNode_t*)GetListNode(tree1->root->child, 2)->data)->data = tmpInt;

printf("%d\n", *(int*)tree1->root->data);
printf("%d\n", *(int*)((ListNode_t*)GetListNode(tree1->root->child, 1)->data)->data);
printf("%d\n", *(int*)((ListNode_t*)GetListNode(tree1->root->child, 2)->data)->data);

printf("\n");
printf("\n");

printf("%d\n", *(int*)tree1->root->data);
printf("%d\n", *(int*)((ListNode_t*)GetListNode(tree1->root->child, 1)->data)->data);
printf("%d\n", *(int*)((ListNode_t*)GetListNode(tree1->root->child, 2)->data)->data);

printf("\n");
printf("\n");

TraverseTree(tree1, printTree);



printf("\n");
printf("\n");

printf("TestTree is end!\n");

printf("\n");
printf("\n");

return DSC_OK;
}


在测试下面这段的时候一切正常,printf两遍都正常,数据并没有丢失。


printf("%d\n", *(int*)tree1->root->data);
printf("%d\n", *(int*)((ListNode_t*)GetListNode(tree1->root->child, 1)->data)->data);
printf("%d\n", *(int*)((ListNode_t*)GetListNode(tree1->root->child, 2)->data)->data);


但是执行TraverseTree(tree1, printTree)的时候就出现问题了,我分别使用了CodeBlocks和VS 2008进行了调试跟踪。

使用CodeBlocks的时候,查看内存数据,一直都很正常,直到把root的第一个子节点送入printTree的时候都还正常,我断点在printTree的printf那行,不执行之前一切正常,执行了就报错,具体错误看不懂,大概就是信号机制报错的。

而使用VS2008的时候,在送入printTree之前,该子节点的data字段就显示0x0,其他正常,但是我在CodeBlocks里调试的时候,通过CodeBlocks的内存查看看到是正常的,而且VS2008报错是

DsClass.exe 中的 0x00413636 处最可能的异常: 0xC0000005: 读取位置 0x00000000 时发生访问冲突
DsClass.exe 中的 0x00413636 处未处理的异常: 0xC0000005: 读取位置 0x00000000 时发生访问冲突

我在想是不是就像变量的内存区块被锁定了这样的事发生呢?

当然,这个程序可能在遍历的时候,用for来代替TraverseList可以解决问题,但是我希望知道这个问题的真相,求高手解答这个问题的真相,非常感谢!
...全文
120 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
cattycat 2010-07-08
  • 打赏
  • 举报
回复
楼主提问还能码这么多字,真是有心啊。不过你是二叉树么,看起来看像是个双向链表啊,parent指向前面,child指向后面。二叉树有两个孩子节点的。
aizibion 2010-07-08
  • 打赏
  • 举报
回复
欣喜地接分~~
屎带芬 2010-07-08
  • 打赏
  • 举报
回复
不客气了,接分!
屎带芬 2010-07-08
  • 打赏
  • 举报
回复
恭喜lz啦!
那就不可了,接分啦!
太乙 2010-07-08
  • 打赏
  • 举报
回复
赞lz~~~
xyalter 2010-07-08
  • 打赏
  • 举报
回复
额。。我自己找到问题了。。。
是其中一个应转成TreeNode_t*而非ListNode_t*。。

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧