user-0 提问: 奇怪的结构体变量声明问题

回复:
user: user-1
content: 建议贴出你的代码，但从数据结构不能看出问题所在。

user: user-2
content: 可能是申请的内存空间不够导致越界访问

user: user-2
content: 引用 8 楼 Love_Irelia97 的回复:引用 1 楼 paschen 的回复:可能是申请的内存空间不够导致越界访问嗯。。。好像是我申请结点的时候错了 node = (Node*)malloc(sizeof(node)); 这里应该是sizeof(*node)，可是为什么之前的结构体又可以呢？  可以不能得出正确，最多说明你运气好，这是未定义行为，就是说可以表现为任何情况

user: user-0
content: 应该改为：  node = (Node*)malloc(sizeof(Node)); if (!node)     exit(0);  [/quote]嗯嗯，你是对的，但非常奇怪的是不添加这两个变量，或者改成我贴出的完整代码那样就可以正常运行，不知道为什么

user: user-0
content: 引用 1 楼 paschen 的回复:可能是申请的内存空间不够导致越界访问嗯。。。好像是我申请结点的时候错了 node = (Node*)malloc(sizeof(node)); 这里应该是sizeof(*node)，可是为什么之前的结构体又可以呢？

user: user-3
content: 感觉内存越界了？

user: user-1
content: 引用 6 楼 Love_Irelia97 的回复:[quote=引用 2 楼 cfjtaishan 的回复:] 建议贴出你的代码，但从数据结构不能看出问题所在。/* Advanced Tree */ #include <stdio.h> #include <stdlib.h> #define MaxSize 100  typedef int ElementType; typedef struct nTree* pTree; typedef struct nTree	//	线索二叉树定义  { 	ElementType data; 	pTree left; 	pTree right; 	int lflag;	 	int rflag; }Node;  /*	非递归建立二叉查找树	*/ void InsertTree(ElementType X, pTree &root) { 	Node *node, *bt, *pre; 	node = (Node*)malloc(sizeof(node)); 	node->left = node->right = NULL; //	node->lflag = node->rflag = 0; 	node->data = X;	  	pre = bt = root;	//	node新结点，bt遍历结点，pre为 bt前驱结点  	while(NULL != bt) 	{ 		pre = bt; 		if(X < bt->data) 			bt = bt->left; 		else if(X > bt->data) 			bt = bt->right;		 	} 	if(NULL == pre)		//	空树  		root = node; 	else if(pre->data > X) 		pre->left  = node; 	else 		pre->right = node; }  void Visit(const pTree bt) { 	printf("%d  ", bt->data); }  int GetTreeHeight(const pTree bt) { 	int l_height= 0, r_height = 0; 	if(NULL == bt) 		return 0; 	else 	{ 		l_height = GetTreeHeight(bt->left); 		r_height = GetTreeHeight(bt->right); 		return (l_height>r_height ? l_height:r_height)+1; 	} }  void PreOrder(const pTree bt) { 	int top = -1; 	pTree stack[MaxSize]; 	pTree p; 	 	if(NULL != bt) 	{ 		stack[++top] = bt; 		while(-1 != top) 		{ 			p = stack[top--]; 			Visit(p); 			if(NULL != p->right) 				stack[++top] = p->right; 			if(NULL != p->left) 				stack[++top] = p->left; 		} 	} 	putchar('\n'); }  void MidOrder(const pTree bt) { 	int top = -1; 	pTree stack[MaxSize]; 	pTree p = bt; 	 	while(p!=NULL || top!=-1) 	{ 		while(p!=NULL) 		{ 			stack[++top] = p; 			p = p->left; 		} 		if(top != -1) 		{ 			p = stack[top--]; 			Visit(p); 			p = p->right; 		} 	} 	putchar('\n'); }  void PostOrder(const pTree bt) { 	int top1 = -1, top2 = -1; 	pTree stack1[MaxSize], stack2[MaxSize]; 	pTree tmp; 	 	if(NULL != bt) 	{ 		stack1[++top1] = bt; 		while(-1 != top1) 		{ 			tmp = stack1[top1--]; //			Visit(tmp); 			stack2[++top2] = tmp; 			if(tmp->left != NULL) 				stack1[++top1] = tmp->left; 			if(tmp->right != NULL) 				stack1[++top1] = tmp->right; 		} 	} 	while(-1 != top2) 		Visit(stack2[top2--]); 	putchar('\n');	 } 			 		 int main() { 	bool falg = false; 	int data[] = {6, 1, 2 ,8 ,10, 5, 0, 7, 3, 9, 4}; 	pTree root = NULL; 	 	for(int i = 0; i <= 10; ++i) 		InsertTree(data[i], root); 	/* 					6 			1				8 		0	  2			7	    10	 				5              9 			   3 			    4			 	*/ 	printf("%d\n", GetTreeHeight(root)); 	PreOrder(root); 	MidOrder(root); 	PostOrder(root);	 	return 0; }   就是这样的代码，把结构体定义换成下面这样就不行了 typedef struct tree    //    线索二叉树定义  {     ElementType data;     pTree left;     int lflag;        pTree right;     int rflag; }Node; [/quote] node = (Node*)malloc(sizeof(node));  问题在这一句，申请的空间不足。我想即使不加这两个参数，一样也会有问题。 node是指针，那么sizeof(node)等价与sizeof(int *)，即指针变量的sizeof值是４（３２位系统里）。 应该改为：  node = (Node*)malloc(sizeof(Node)); if (!node)     exit(0);

user: user-0
content: 引用 2 楼 cfjtaishan 的回复:建议贴出你的代码，但从数据结构不能看出问题所在。/* Advanced Tree */ #include <stdio.h> #include <stdlib.h> #define MaxSize 100  typedef int ElementType; typedef struct nTree* pTree; typedef struct nTree	//	线索二叉树定义  { 	ElementType data; 	pTree left; 	pTree right; 	int lflag;	 	int rflag; }Node;  /*	非递归建立二叉查找树	*/ void InsertTree(ElementType X, pTree &root) { 	Node *node, *bt, *pre; 	node = (Node*)malloc(sizeof(node)); 	node->left = node->right = NULL; //	node->lflag = node->rflag = 0; 	node->data = X;	  	pre = bt = root;	//	node新结点，bt遍历结点，pre为 bt前驱结点  	while(NULL != bt) 	{ 		pre = bt; 		if(X < bt->data) 			bt = bt->left; 		else if(X > bt->data) 			bt = bt->right;		 	} 	if(NULL == pre)		//	空树  		root = node; 	else if(pre->data > X) 		pre->left  = node; 	else 		pre->right = node; }  void Visit(const pTree bt) { 	printf("%d  ", bt->data); }  int GetTreeHeight(const pTree bt) { 	int l_height= 0, r_height = 0; 	if(NULL == bt) 		return 0; 	else 	{ 		l_height = GetTreeHeight(bt->left); 		r_height = GetTreeHeight(bt->right); 		return (l_height>r_height ? l_height:r_height)+1; 	} }  void PreOrder(const pTree bt) { 	int top = -1; 	pTree stack[MaxSize]; 	pTree p; 	 	if(NULL != bt) 	{ 		stack[++top] = bt; 		while(-1 != top) 		{ 			p = stack[top--]; 			Visit(p); 			if(NULL != p->right) 				stack[++top] = p->right; 			if(NULL != p->left) 				stack[++top] = p->left; 		} 	} 	putchar('\n'); }  void MidOrder(const pTree bt) { 	int top = -1; 	pTree stack[MaxSize]; 	pTree p = bt; 	 	while(p!=NULL || top!=-1) 	{ 		while(p!=NULL) 		{ 			stack[++top] = p; 			p = p->left; 		} 		if(top != -1) 		{ 			p = stack[top--]; 			Visit(p); 			p = p->right; 		} 	} 	putchar('\n'); }  void PostOrder(const pTree bt) { 	int top1 = -1, top2 = -1; 	pTree stack1[MaxSize], stack2[MaxSize]; 	pTree tmp; 	 	if(NULL != bt) 	{ 		stack1[++top1] = bt; 		while(-1 != top1) 		{ 			tmp = stack1[top1--]; //			Visit(tmp); 			stack2[++top2] = tmp; 			if(tmp->left != NULL) 				stack1[++top1] = tmp->left; 			if(tmp->right != NULL) 				stack1[++top1] = tmp->right; 		} 	} 	while(-1 != top2) 		Visit(stack2[top2--]); 	putchar('\n');	 } 			 		 int main() { 	bool falg = false; 	int data[] = {6, 1, 2 ,8 ,10, 5, 0, 7, 3, 9, 4}; 	pTree root = NULL; 	 	for(int i = 0; i <= 10; ++i) 		InsertTree(data[i], root); 	/* 					6 			1				8 		0	  2			7	    10	 				5              9 			   3 			    4			 	*/ 	printf("%d\n", GetTreeHeight(root)); 	PreOrder(root); 	MidOrder(root); 	PostOrder(root);	 	return 0; }   就是这样的代码，把结构体定义换成下面这样就不行了 typedef struct tree    //    线索二叉树定义  {     ElementType data;     pTree left;     int lflag;        pTree right;     int rflag; }Node;

user: user-4
content: 看一下申请空间的的代码，是不是申请的不够，单个结构体变大了，总体需要的空间也变大了，如果没有操作这两个新加的属性，可以看看是不是越界了

user: user-5
content: “给定一个小点的输入，完整单步跟踪(同时按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史)一遍。”是理解递归函数工作原理的不二法门！ 递归函数关注以下几个因素 ·退出条件 ·参数有哪些 ·返回值是什么 ·局部变量有哪些 ·全局变量有哪些 ·何时输出 ·会不会导致堆栈溢出

user: user-5
content: 仅供参考：#include <locale.h> #include <stdio.h> #include <stdlib.h> #include <malloc.h> typedef struct BiTNode {//二叉树结点     char data;                      //数据     struct BiTNode *lchild,*rchild; //左右孩子指针 } BiTNode,*BiTree; int nn=0; int CreateBiTree(BiTree *T) {//按先序序列创建二叉树     char data;     scanf("%c",&data);//按先序次序输入二叉树中结点的值（一个字符），‘#’表示空树     if (data == '#') {         *T = NULL;     } else {         *T = (BiTree)malloc(sizeof(BiTNode)); nn++;         (*T)->data = data;         //生成根结点         CreateBiTree(&(*T)->lchild);//构造左子树         CreateBiTree(&(*T)->rchild);//构造右子树     }     return 0; } void Visit(BiTree T) {//输出     if (T->data != '#') {         printf("%c ",T->data);     } } void PreOrder(BiTree T) {//先序遍历     if (T != NULL) {         Visit(T);               //访问根节点         PreOrder(T->lchild);    //访问左子结点         PreOrder(T->rchild);    //访问右子结点     } } void InOrder(BiTree T) {//中序遍历     if (T != NULL) {         InOrder(T->lchild);     //访问左子结点         Visit(T);               //访问根节点         InOrder(T->rchild);     //访问右子结点     } } void PostOrder(BiTree T) {//后序遍历     if (T != NULL) {         PostOrder(T->lchild);   //访问左子结点         PostOrder(T->rchild);   //访问右子结点         Visit(T);               //访问根节点     } } void PreOrder2(BiTree T) {//先序遍历(非递归) //访问T->data后，将T入栈，遍历左子树；遍历完左子树返回时，栈顶元素应为T，出栈，再先序遍历T的右子树。     BiTree *stack=(BiTree *)malloc(nn*sizeof(BiTree));     int sp=0;     BiTree p = T;//p是遍历指针     while (p || sp) {   //栈不空或者p不空时循环         if (p != NULL) {             stack[sp]=p;sp++;       //存入栈中             printf("%c ",p->data);  //访问根节点             p = p->lchild;          //遍历左子树         } else {             sp--;p=stack[sp];       //退栈             p = p->rchild;          //访问右子树         }     }     free(stack); } void InOrder2(BiTree T) {//中序遍历(非递归) //T是要遍历树的根指针，中序遍历要求在遍历完左子树后，访问根，再遍历右子树。 //先将T入栈，遍历左子树；遍历完左子树返回时，栈顶元素应为T，出栈，访问T->data，再中序遍历T的右子树。     BiTree *stack=(BiTree *)malloc(nn*sizeof(BiTree));     int sp=0;     BiTree p = T;//p是遍历指针     while (p || sp) {   //栈不空或者p不空时循环         if (p != NULL) {             stack[sp]=p;sp++;       //存入栈中             p = p->lchild;          //遍历左子树         } else {             sp--;p=stack[sp];       //退栈             printf("%c ",p->data);             p = p->rchild;          //访问右子树         }     }     free(stack); }  typedef struct BiTNodePost{     BiTree biTree;     char tag; } BiTNodePost,*BiTreePost; void PostOrder2(BiTree T) {//后序遍历(非递归)     BiTreePost *stack=(BiTreePost *)malloc(nn*sizeof(BiTreePost));     int sp=0;     BiTree p = T;//p是遍历指针     BiTreePost BT;     while (p != NULL || sp) {//栈不空或者p不空时循环         while (p != NULL) {//遍历左子树             BT = (BiTreePost)malloc(sizeof(BiTNodePost));             BT->biTree = p;             BT->tag = 'L';//访问过左子树             stack[sp]=BT;sp++;       //存入栈中             p = p->lchild;         }         while (sp && (stack[sp-1])->tag == 'R') {//左右子树访问完毕访问根节点             sp--;BT=stack[sp];        //退栈             printf("%c ",BT->biTree->data);             free(BT);         }         if (sp) {//遍历右子树             BT=stack[sp-1];             BT->tag = 'R';//访问过右子树             p = BT->biTree;             p = p->rchild;         }     }     free(stack); } void LevelOrder(BiTree T) {//层次遍历     BiTree p;     BiTree *queue;     int h=0,t=0,n=0;      if (T == NULL) return;     p=T;     queue=(BiTree *)malloc(nn*sizeof(BiTree));     queue[t]=p;t=(t+1)%10;n++;//根节点入队     while (n) {    //队列不空循环         p=queue[h];             //对头元素出队         printf("%c ",p->data);  //访问p指向的结点         h=(h+1)%10;n--;         //退出队列         if (p->lchild != NULL) {//左子树不空，将左子树入队             queue[t]=p->lchild;t=(t+1)%10;n++;         }         if (p->rchild != NULL) {//右子树不空，将右子树入队             queue[t]=p->rchild;t=(t+1)%10;n++;         }     }     free(queue); } int main() {     BiTree T;      setlocale(LC_ALL,"chs");     CreateBiTree(&T);      printf("先序遍历        ：");PreOrder  (T);printf("\n");     printf("先序遍历(非递归)：");PreOrder2 (T);printf("\n");                                                printf("\n");     printf("中序遍历        ：");InOrder   (T);printf("\n");     printf("中序遍历(非递归)：");InOrder2  (T);printf("\n");                                                printf("\n");     printf("后序遍历        ：");PostOrder (T);printf("\n");     printf("后序遍历(非递归)：");PostOrder2(T);printf("\n");                                                printf("\n");     printf("层次遍历        ：");LevelOrder(T);printf("\n");      return 0; } //ABC##DE#G##F### //先序遍历        ：A B C D E G F //先序遍历(非递归)：A B C D E G F // //中序遍历        ：C B E G D F A //中序遍历(非递归)：C B E G D F A // //后序遍历        ：C G E F D B A //后序遍历(非递归)：C G E F D B A // //层次遍历        ：A B C D E F G //  ///       A ///      / ///     B ///    / \ ///   C   D ///      / \ ///     E   F ///      \ ///       G