C 传递指针引起程序异常退出
本帖最后由 ing 于 2020-1-29 21:20 编辑如图断点处,为什么这样 enQueue(&q,t) 传递指针会使程序异常?
如果改成 &t(或者 t) 就不会异常,但得到的结果不是我想要的,这个结果说明 enQueue() 方法没有生效
修改方法 enQueue 的参数 Tree *t 为 Tree t 后
enQueue(Queueq,Tree *** t**) ⇒ enQueue(Queueq,**Tree t**)
再将传递给 enQueue 方法的参数 &t 改为 (*t) 程序才正确运行,但这是为什么?我不理解
我的爱是你 发表于 2020-1-29 12:47
我很奇怪你们都是用的什么编译器?
我vs直接爆出了16个错误无法进行编译。
...我的问题是
如果入队方法是这样 enqueue(Queue ** q,Tree * t)
那么传递给他的参数(Tree)那里必须是 enQueue(..,(*t));
否则程序异常或得不到结果。
但我不理解为什么不能传入 t 而是 *t。 本帖最后由 我的爱是你 于 2020-1-29 19:43 编辑
抱歉抱歉{:301_995:}
脑子有坑了,修改结构体是最愚蠢最愚蠢的做法。。。。
既然给了指针而结构体不需要指针只需要指针内的参数,那么直接取指针值也是一样。。。。修改结构体工作量要上天了!
以下运行结果:↓
改完函数后把这两处改完即可顺利运行。 完整代码
```
#include<stdarg.h>
#include<malloc.h>
#include<stdio.h>
#define MAX_VERTEX_NUM 50
#define VType int
#define InfoType char
typedef enum {false,true} bool;
bool visited;
typedef struct
{
int weight;
InfoType info;
}Matrix;
typedef struct
{
VType vertex;
Matrix arcs;
int arcNum,vertexNum;
}MGraph;
typedef struct Node
{
VType data;
struct Node * l_child;
struct Node * nextSibling;
}*Tree,Node;
typedef struct Queue
{
//队列中存放的为树结点
Tree node;
struct Queue * next;
}Queue;
int locateVertex(MGraph *g, VType vertex)
{
for (int i = 0; i < g->vertexNum; ++i) {
if (g->vertex == vertex)
{
return i;
}
}
return -1;
}
void createDN(MGraph * g)
{
g->arcNum = 13;
g->vertexNum = 13;
// printf("请输入顶点数据 \n");
// for (int i = 0; i < g->vertexNum; ++i) {
// //strtol
// scanf("%d",&(g->vertex));
// }
for (int i = 0; i < g->vertexNum; ++i) {
//strtol
g->vertex = i+1;
}
for (int k = 0; k < g->vertexNum; ++k) {
for (int i = 0; i < g->vertexNum; ++i) {
g->arcs.weight = 00;
g->arcs.info = NULL;
}
}
// printf("请输入弧头和弧尾 \n");
// for (int j = 0; j < g->vertexNum; ++j) {
// VType v1,v2;
// scanf("%d,%d",&v1,&v2);
// int n = locateVertex(g,v1);
// int m = locateVertex(g,v2);
// g->arcs.weight = 1;
// g->arcs.weight = 1;
// }
int n = 0, m = 1;
g->arcs.weight = 1;
g->arcs.weight = 1;
m = 2;
g->arcs.weight = 1;
g->arcs.weight = 1;
m = 5;
g->arcs.weight = 1;
g->arcs.weight = 1;
n = 0, m = 11;
g->arcs.weight = 1;
g->arcs.weight = 1;
n = 1, m = 12;
g->arcs.weight = 1;
g->arcs.weight = 1;
n = 4, m = 2;
g->arcs.weight = 1;
g->arcs.weight = 1;
m = 7, n = 6;
g->arcs.weight = 1;
g->arcs.weight = 1;
m = 9;
g->arcs.weight = 1;
g->arcs.weight = 1;
m = 8;
g->arcs.weight = 1;
g->arcs.weight = 1;
n = 7, m = 9;
g->arcs.weight = 1;
g->arcs.weight = 1;
n = 11,m=10;
g->arcs.weight = 1;
g->arcs.weight = 1;
n=12;
g->arcs.weight = 1;
g->arcs.weight = 1;
m=11;
g->arcs.weight = 1;
g->arcs.weight = 1;
}
void initQueue(Queue ** q)
{
(*q) = (Queue*)malloc(sizeof(Queue));
(*q)->next = NULL;
}
void deQueue(Queue ** q,Tree * t)
{
(*t) = (*q)->next->node;
(*q)->next = (*q)->next->next;
}
bool isEmpty(Queue * q)
{
if (q->next)
return false;
else
return true;
}
int firstAdjVex(MGraph * g,int v)
{
for (int i = 0; i < g->vertexNum; ++i) {
if (g->arcs.weight == 1)
{
return i;
}
}
return -1;
}
int nextAdjVex(MGraph * g,int v,int w)
{
for (int i = w+1; i < g->vertexNum; ++i) {
if (g->arcs.weight == 1)
{
return i;
}
}
return -1;
}
void enQueue(Queue ** q,Tree t)
{
Queue * e = malloc(sizeof(Queue));
e->node = t;
e->next = NULL;
Queue * temp = (*q);
while (temp->next)
{
temp = temp->next;
}
temp->next = e;
}
//Tree t
void bfsTree(MGraph * g,Tree * t)
{
Queue * q = NULL;
initQueue(&q);
//根结点入队
enQueue(&q, (*t)); // t
//存储出队列的结点
Tree p = NULL;
//while (q)
while (!isEmpty(q))
{
bool first = true;
deQueue(&q,&p);
//判断出队结点中的数据在数组中的具体位置
int v = locateVertex(g,p->data);
visited = true;
for (int i = firstAdjVex(g,v); i > -1; i = nextAdjVex(g,v,i)) {
if (!visited)
{
Tree temp = malloc(sizeof(Node));
temp->data = g->vertex;
temp->l_child = NULL;
temp->nextSibling = NULL;
enQueue(&q,temp);
if (first)
{
p->l_child = temp;
first = false;
}
else
{
p->nextSibling = temp;
}
visited = true;
p = temp;
}
}
}
}
//Tree t
void bfsForest(MGraph * g, Tree * t)
{
(*t) = NULL;
Tree q = NULL;
for (int i = 0; i < g->vertexNum; ++i) {
visited = false;
}
for (int j = 0; j < g->vertexNum; ++j) {
if (!visited)
{
Tree p = malloc(sizeof(Node));
p->data = g->vertex;
p->nextSibling = NULL;
p->l_child = NULL;
//如果树为空,则该顶点作为树的树根
if (!(*t))
{
(*t) = p;
}
else
{
q->nextSibling = p;
}
q = p;
bfsTree(g,t);
}
}
}
void preOrderTraverse(Tree t)
{
if (t)
{
printf("%d ",t->data);
preOrderTraverse(t->l_child);
preOrderTraverse(t->nextSibling);
}
}
int main(int argc, char* argv[])
{
MGraph g;
createDN(&g);
Tree t;
bfsForest(&g,&t);
preOrderTraverse(t);
return 0;
}
``` 广搜?
没看懂你问的问题,, 本帖最后由 我的爱是你 于 2020-1-29 12:49 编辑
我很奇怪你们都是用的什么编译器?
我vs直接爆出了16个错误无法进行编译。
以下是我修改的。
#include<stdarg.h>
#include<malloc.h>
#include<stdio.h>
#define MAX_VERTEX_NUM 50
#define VType int
#define InfoType char
typedef enum { False, TRUE } boo;
boo visited;
typedef struct
{
int weight;
InfoType info;
}Matrix;
typedef struct
{
VType vertex;
Matrix arcs;
int arcNum, vertexNum;
}MGraph;
typedef struct Node
{
VType data;
struct Node* l_child;
struct Node* nextSibling;
}*Tree, Node;
typedef struct Queue
{
//队列中存放的为树结点
Tree node;
struct Queue* next;
}Queue;
int locateVertex(MGraph* g, VType vertex)
{
for (int i = 0; i < g->vertexNum; ++i) {
if (g->vertex == vertex)
{
return i;
}
}
return -1;
}
void createDN(MGraph* g)
{
g->arcNum = 13;
g->vertexNum = 13;
// printf("请输入顶点数据 \n");
// for (int i = 0; i < g->vertexNum; ++i) {
// //strtol
// scanf("%d",&(g->vertex));
// }
for (int i = 0; i < g->vertexNum; ++i) {
//strtol
g->vertex = i + 1;
}
for (int k = 0; k < g->vertexNum; ++k) {
for (int i = 0; i < g->vertexNum; ++i) {
g->arcs.weight = 00;
g->arcs.info = NULL;
}
}
// printf("请输入弧头和弧尾 \n");
// for (int j = 0; j < g->vertexNum; ++j) {
// VType v1,v2;
// scanf("%d,%d",&v1,&v2);
// int n = locateVertex(g,v1);
// int m = locateVertex(g,v2);
// g->arcs.weight = 1;
// g->arcs.weight = 1;
// }
int n = 0, m = 1;
g->arcs.weight = 1;
g->arcs.weight = 1;
m = 2;
g->arcs.weight = 1;
g->arcs.weight = 1;
m = 5;
g->arcs.weight = 1;
g->arcs.weight = 1;
n = 0, m = 11;
g->arcs.weight = 1;
g->arcs.weight = 1;
n = 1, m = 12;
g->arcs.weight = 1;
g->arcs.weight = 1;
n = 4, m = 2;
g->arcs.weight = 1;
g->arcs.weight = 1;
m = 7, n = 6;
g->arcs.weight = 1;
g->arcs.weight = 1;
m = 9;
g->arcs.weight = 1;
g->arcs.weight = 1;
m = 8;
g->arcs.weight = 1;
g->arcs.weight = 1;
n = 7, m = 9;
g->arcs.weight = 1;
g->arcs.weight = 1;
n = 11, m = 10;
g->arcs.weight = 1;
g->arcs.weight = 1;
n = 12;
g->arcs.weight = 1;
g->arcs.weight = 1;
m = 11;
g->arcs.weight = 1;
g->arcs.weight = 1;
}
void initQueue(Queue** q)
{
(*q) = (Queue*)malloc(sizeof(Queue));
(*q)->next = NULL;
}
void deQueue(Queue** q, Tree* t)
{
(*t) = (*q)->next->node;
(*q)->next = (*q)->next->next;
}
boo isEmpty(Queue* q)
{
if (q->next)
return False;
else
return TRUE;
}
int firstAdjVex(MGraph* g, int v)
{
for (int i = 0; i < g->vertexNum; ++i) {
if (g->arcs.weight == 1)
{
return i;
}
}
return -1;
}
int nextAdjVex(MGraph* g, int v, int w)
{
for (int i = w + 1; i < g->vertexNum; ++i) {
if (g->arcs.weight == 1)
{
return i;
}
}
return -1;
}
void enQueue(Queue** q, Tree t)
{
Queue* e = (struct Queue*)malloc(sizeof(Queue));
e->node = t;
e->next = NULL;
Queue* temp = (*q);
while (temp->next)
{
temp = temp->next;
}
temp->next = e;
}
//Tree t
void bfsTree(MGraph* g, Tree* t)
{
Queue* q = NULL;
initQueue(&q);
//根结点入队
enQueue(&q, (*t)); // t
//存储出队列的结点
Tree p = NULL;
//while (q)
while (!isEmpty(q))
{
boo first = TRUE;
deQueue(&q, &p);
//判断出队结点中的数据在数组中的具体位置
int v = locateVertex(g, p->data);
visited = TRUE;
for (int i = firstAdjVex(g, v); i > -1; i = nextAdjVex(g, v, i)) {
if (!visited)
{
Tree temp = (struct Node*)malloc(sizeof(Node));
temp->data = g->vertex;
temp->l_child = NULL;
temp->nextSibling = NULL;
enQueue(&q, temp);
if (first)
{
p->l_child = temp;
first = False;
}
else
{
p->nextSibling = temp;
}
visited = TRUE;
p = temp;
}
}
}
}
//Tree t
void bfsForest(MGraph* g, Tree* t)
{
(*t) = NULL;
Tree q = NULL;
for (int i = 0; i < g->vertexNum; ++i) {
visited = False;
}
for (int j = 0; j < g->vertexNum; ++j) {
if (!visited)
{
Tree p = (struct Node*)malloc(sizeof(Node));
p->data = g->vertex;
p->nextSibling = NULL;
p->l_child = NULL;
//如果树为空,则该顶点作为树的树根
if (!(*t))
{
(*t) = p;
}
else
{
q->nextSibling = p;
}
q = p;
bfsTree(g, t);
}
}
}
void preOrderTraverse(Tree t)
{
if (t)
{
printf("%d ", t->data);
preOrderTraverse(t->l_child);
preOrderTraverse(t->nextSibling);
}
}
int main(int argc, char* argv[])
{
MGraph g;
createDN(&g);
Tree t;
bfsForest(&g, &t);
preOrderTraverse(t);
return 0;
}
这个是楼主想要的结果?
你这个malloc怎么可以不定义返回的结构指针!
还有你这个宏为啥直接能用bool命名。。
我进行了以上修改就没有任何问题了。lz的错误在于语法问题。{:301_971:}
本帖最后由 ing 于 2020-1-29 16:09 编辑
我的爱是你 发表于 2020-1-29 12:47
我很奇怪你们都是用的什么编译器?
我vs直接爆出了16个错误无法进行编译。
我用Clion,VS跑程序会出错我都不知道是什么原因。。
我在Clion定义返回的结构指针是这样的形式 (Queue*) ,没有struct
后来发现不写也不影响,就懒得写了我不知道这是必须的{:1_907:}
你这是C++吧?因为后缀不是 .c;
然后 bool 功能是要自己实现的。。
最后,能加我吗?我不知道怎么玩 VS,在Clion可运行的代码放VS就异常 ing 发表于 2020-1-29 15:58
我用Clion,VS跑程序会出错我都不知道是什么原因。。
我在Clion定义返回的结构指针是这样的形式 (Queue* ...
我这是c ,cpp只不过是新建文件懒得改了。
void返回理论可以是任何返回,但规范来说malloc为你申请了一篇内存域 ,你理应按照语法返回指针为该申请的结构类型。
另外我知道bool被你重定义为枚举类型,但我没记错的话bool变量在编译器内已经使用typedef进行过宏定义,你这不亚于用int重定义char类型 命名是不规范的。 本帖最后由 我的爱是你 于 2020-1-29 18:19 编辑
ing 发表于 2020-1-29 15:50
...我的问题是
如果入队方法是这样 enqueue(Queue ** q,Tree * t)
那么传递给他的参数(Tree)那里必须 ...
void bfsTree(MGraph* g, Tree* t)
你这里函数不是定义t为指针了吗,你直接enQueue(&q,t) 是传给了它一个指针
而你这个函数void enQueue(Queue** q, Tree t)第二参数只接受实参 ,
而 * 这个符号名字叫做取值符,你怕是忘了加了这个在t上意思为将t指针所指向的值取出。
也就是将取出的值给予了第二参数 ,并不是将指针给予了第二参数。这个问题太明显了!
你想要enQueue(&q,t)它接受t指针也就是必须void enQueue(Queue** q, Tree* t)这样。否自就必须加上取值符。 我的爱是你 发表于 2020-1-29 17:50
你这里函数不是定义t为指针了 ...
可如果方法这样 void enQueue(Queue** q, Tree* t)
再这样调用 enQueue(&q,t)
就出现了第一张图片的运行结果,异常退出了。
然后,在 bfsForest 方法的最后一行代码是 bfsTree(g, t);
然而这个方法这样的声明 `void bfsTree(MGraph * g,Tree * t)` 却是可行的。
在定义函数 enQueue 这里却翻车了
改完函数确实可以接受指针,但你结构也应当做相应改变
否则node本来接受一个实参,现在你给它了一个指针并不匹配接受到的指针当然会出错。
同时第二个enQueue既然第二个参数接受指针 ,那么原来的temp也需要改动。
这里enQueue(&q, &temp);可以直接将temp地址给予参数二。
如都不进行改动 自然报错{:301_1008:}
页:
[1]
2