user-0 提问: 一条malloc语句引发的血案

回复:
user: user-0
content: 引用 16 楼 lin5161678 的回复:xlist是一个数组越界读写操作是未定义行为 未定义行为没有保证错误 会不会错误 会出现什么样的错误 看具体运行环境 这里这块内存有写入权限 你写数据就没问题 但是写入的数据把堆信息覆盖了 所有依赖堆信息的操作都可能出错 比如这里后面的malloc需要依靠这些堆信息查找内存块 所以malloc执行出错 也可以malloc没出错  但是free的时候获取到的堆信息错误而执行失败 可能性很多 谢谢

user: user-1
content: xlist是一个数组越界读写操作是未定义行为 未定义行为没有保证错误 会不会错误 会出现什么样的错误 看具体运行环境 这里这块内存有写入权限 你写数据就没问题 但是写入的数据把堆信息覆盖了 所有依赖堆信息的操作都可能出错 比如这里后面的malloc需要依靠这些堆信息查找内存块 所以malloc执行出错 也可以malloc没出错  但是free的时候获取到的堆信息错误而执行失败 可能性很多

user: user-0
content: 引用 10 楼 lin5161678 的回复:Graph 这个变量名和你的结构体名字重复 按照作用域 函数内部的Graph这个标识符表示一个指针  malloc 一个指针大小 后面按照一个结构体进行读写  越界导致破坏堆信息 所以malloc出错  改个名字就完事了能再问一下吗，malloc一个指针大小是不是，就是Graph指向了一个指针大小的堆内存空间，那么下面按个for循环初始化顶点向量xlist[MAX]的时候(这里我不知道xlist是一个指针放在这块堆内存还是整个数组放在这个堆内存内，如果是一个指针，那这块内存就是放了两个int变量加一个指针，所以越界了，如果是整个数组就更大了，肯定越界了），应该就破坏堆内存了，为什么到还能运行到下一个for循环的malloc语句？ 不知道我上面这个理解对了多少。。。

user: user-0
content: 引用 10 楼 lin5161678 的回复:Graph 这个变量名和你的结构体名字重复 按照作用域 函数内部的Graph这个标识符表示一个指针  malloc 一个指针大小 后面按照一个结构体进行读写  越界导致破坏堆信息 所以malloc出错  改个名字就完事了厉害

user: user-2
content: 请输入顶点数和边数9 6 请输入第1条边1 3 0x7ffeefbff550stopbreak请输入第2条边 运行，妹的没有毛病

user: user-3
content: 你的变量名为什么要定义成和类型名一样呢？没有其他名字了吗？

user: user-1
content: MGraph Graph=(MGraph)malloc(sizeof(Graph));

user: user-1
content: Graph 这个变量名和你的结构体名字重复 按照作用域 函数内部的Graph这个标识符表示一个指针  malloc 一个指针大小 后面按照一个结构体进行读写  越界导致破坏堆信息 所以malloc出错  改个名字就完事了

user: user-0
content: 因为前面就直接闪没了，所以我觉得没有看后面代码的必要，之前就没发

user: user-0
content: 大神，再看看，不行的话我重打一编。。。。。 代码全部在这里 #include<stdio.h> #include<stdlib.h> #define MAX 100 struct AdjNode{ 	int tailvex,headvex; 	AdjNode *hlink,*tlink; }; typedef struct VexNode{ 	int vertex; 	AdjNode *firstin,*firstout; }XList[MAX]; struct Graph{ 	int vexnum,arcnum; 	XList xlist; }; typedef Graph* MGraph; MGraph CreateGraph() { 	MGraph Graph=(MGraph)malloc(sizeof(Graph)); 	printf("请输入顶点数和边数"); 	scanf("%d%d",&Graph->vexnum,&Graph->arcnum); 	AdjNode *p=(AdjNode*)malloc(sizeof(AdjNode)); 	int i,j,k,l; 	for(i=1;i<=Graph->vexnum;i++){ 		Graph->xlist[i].vertex=i; 		Graph->xlist[i].firstout=Graph->xlist[i].firstin=NULL; 	} 	for(l=1;l<=Graph->arcnum;l++){ 		printf("请输入第%d条边",l); 		scanf("%d%d",&i,&j); 		AdjNode *q; 		printf("%p",q); 		printf("stop"); 						q=(AdjNode*)malloc(sizeof(AdjNode));						//出问题 		printf("break"); 		*q={i,j,Graph->xlist[j].firstin,Graph->xlist[i].firstout}; 		Graph->xlist[i].firstout=Graph->xlist[j].firstin=q; 	} 	return Graph; } int firstarc(MGraph Graph,int v){ 	return Graph->xlist[v].firstout->tailvex; } int nextarc(MGraph Graph,int v,int w){ 	AdjNode* p; 	for(p=Graph->xlist[v].firstout;p->tailvex!=w;p=p->tlink); 	if(p->tlink) return p->tlink->headvex; 	else return -1;  } int* FindIndegree(MGraph Graph) { 	AdjNode* p=NULL; 	int *indegree=(int*)malloc(sizeof(int)*(Graph->vexnum+1)); 	int i; 	for(i=1;i<=Graph->vexnum;i++){ 		p=Graph->xlist[i].firstin;  		while(p){ 			indegree[i]++; 			p=p->hlink; 		} 	} 	return indegree; } struct Stack{ 	int *base,*top; 	int Size; }; void iniStack(Stack &stack){ 	stack.base=stack.top=(int*)malloc(sizeof(int)*MAX); 	stack.Size=MAX-1; } void push(Stack &stack,int x){ 	*(stack.top++)=x; } void pop(Stack &stack,int i){ 	i=*(--stack.top); } bool EmptyStack(Stack &stack){ 	if(stack.base==stack.top) 		return true; 	else return false; } void TopologicalSort(MGraph Graph) {	 	int* indegree=FindIndegree(Graph); 	int v,w,count=0; 	Stack stack; 	iniStack(stack); 	int i=1; 	for(i=1;i<=Graph->arcnum;i++) 	{ 		if(!indegree[i]) push(stack,indegree[i]); 	} 	while(!EmptyStack(stack)){ 		pop(stack,i); 		printf("%d",i); 		++count; 		for(w=firstarc(Graph,i);w>=0;w=nextarc(Graph,v,w)){ 			if(!(--indegree[w])) push(stack,i); 		} 	}  } int main(){ 	MGraph Graph=CreateGraph(); 	TopologicalSort(Graph); }

user: user-2
content: 看不明白为啥      只好总结为： 脸不好

user: user-0
content: 引用 3 楼 寻开心 的回复:下面的那句 *q = {....}倒是有些怀疑 应该不会吧，那*p之前的打印break语句都没显示出来就结束

user: user-0

user: user-4
content: 光看贴出的代码确实没看出来 AdjNode定义的代码也发出来看看吧

user: user-2
content: 下面的那句 *q = {....}倒是有些怀疑

user: user-2
content: 看不出问题。  AdjNode是怎么定义的，也发出来看看

user: user-0